当前位置: 首页 > 面试题库 >

如何使用Mockito或Powermock模拟局部变量

华锦
2023-03-14
问题内容

我有这样的情况

InputStreamReader reader = new InputStreamReader(getFileAsStream(resourceResolver, iconpath));
                BufferedReader bReader = new BufferedReader(reader);

到目前为止我一直在嘲笑

getFileAsStream(resourceResolver, iconpath)

现在我得到一个读者

 BufferedReader bReader = new BufferedReader(reader);

但是当我执行此行时,我得到null并且无法前进

  while ((iconEntry = bReader.readLine()) != null)

请告诉我如何嘲笑这个。请注意,我无法更改我的主要代码,因此在我的情况下,Mockito文档中存在的解决方案无效

测试码

@RunWith(PowerMockRunner.class)
@PrepareForTest({ FrameworkUtil.class, LoggerFactory.class })
public class IconPreviewServletTest {
    private IconPreviewServlet iconPreviewServlet;
    private SlingHttpServletRequest request;
    private SlingHttpServletResponse response;
    private Bundle bundle;
    private BundleContext bundleContext;
    private ServiceReference factoryRef;
    private CommonService resolverFactory;
    private PrintWriter out;
    private ResourceResolver resourceResolver;
    private Resource resource;
    private Node node;
    private Node jcrContent;
    private javax.jcr.Property property;
    private Binary binary;
    private InputStream stream;
    private InputStreamReader inputReader;
    private BufferedReader reader;

    @Before
    public void setUp() throws IOException, PathNotFoundException,
            RepositoryException {
        init();
    }

    private void init() throws IOException, PathNotFoundException,
            RepositoryException {

        request = mock(SlingHttpServletRequest.class);
        response = mock(SlingHttpServletResponse.class);
        bundleContext = mock(BundleContext.class);
        factoryRef = mock(ServiceReference.class);
        resolverFactory = mock(CommonService.class);
        out = mock(PrintWriter.class);
        resourceResolver = mock(ResourceResolver.class);
        resource = mock(Resource.class);
        node = mock(Node.class);
        jcrContent = mock(Node.class);
        property = mock(Property.class);
        binary = mock(Binary.class);
        stream=IOUtils.toInputStream("some test data for my input stream");



        reader = mock(BufferedReader.class);

        inputReader=mock(InputStreamReader.class);

        bundle = mock(Bundle.class);
        mockStatic(FrameworkUtil.class);
        mockStatic(LoggerFactory.class);

        Logger log = mock(Logger.class);

        when(LoggerFactory.getLogger(IconPreviewServlet.class)).thenReturn(log);
        when(FrameworkUtil.getBundle(CommonService.class)).thenReturn(bundle);
        when(bundle.getBundleContext()).thenReturn(bundleContext);
        when(bundleContext.getServiceReference(CommonService.class.getName()))
                .thenReturn(factoryRef);
        when(bundleContext.getService(factoryRef)).thenReturn(resolverFactory);
        when(request.getParameter("category")).thenReturn("category");
        when(request.getParameter("query")).thenReturn("query");
        when(response.getWriter()).thenReturn(out);
        when(request.getResourceResolver()).thenReturn(resourceResolver);
        when(
                resourceResolver
                        .getResource("/etc/designs/resmed/icons/category/icons.txt"))
                .thenReturn(resource);
        when(resource.adaptTo(Node.class)).thenReturn(node);
        when(node.getNode("jcr:content")).thenReturn(jcrContent);
        when(jcrContent.getProperty("jcr:data")).thenReturn(property);
        when(property.getBinary()).thenReturn(binary);
        when(binary.getStream()).thenReturn(stream);

    }

问题答案:

要使此工作正常进行,您需要使用Powermockito来拦截构造函数调用(新的InputStreamReader(…),新的BufferedReader(…)),以便返回模拟。下面是一个示例。在您的情况下,仅拦截新的BufferedReader调用就足够了。

假设以下是您要测试的代码:

package test;

import java.io.*;

public class SUT {

    public String doSomething() throws IOException {
        InputStreamReader reader =
                new InputStreamReader(getFileAsStream(null, null));
        BufferedReader bReader =
                new BufferedReader(reader);

        return bReader.readLine();
    }

    private InputStream getFileAsStream(Object resourceResolver, Object iconPath)
            throws FileNotFoundException {
        return new ByteArrayInputStream("".getBytes());
    }
}

以下测试代码是如何拦截构造函数调用的示例:

package test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SUT.class })
public class SUTTest {

    @Test
    public void doSomethingReturnsValueFromBufferedReader() throws Exception {
        // Arrange
        SUT sut = new SUT();
        InputStreamReader inputStreamReaderMock = mock(InputStreamReader.class);
        BufferedReader bufferedReaderMock = mock(BufferedReader.class);

        // Set your mocks up to be returned when the new ...Reader calls 
        // are executed in sut.doSomething()
        PowerMockito.whenNew(InputStreamReader.class).
                     withAnyArguments().thenReturn(inputStreamReaderMock);
        PowerMockito.whenNew(BufferedReader.class).
                     withArguments(inputStreamReaderMock).
                     thenReturn(bufferedReaderMock);

        // Set the value you want bReader.readLine() to return 
        // when sut.doSomething() executes
        final String bufferedReaderReturnValue = "myValue";
        doReturn(bufferedReaderReturnValue).when(bufferedReaderMock).readLine();

        // Act
        String result = sut.doSomething();

        // Assert
        assertEquals(bufferedReaderReturnValue, result);
    }
}

希望这可以帮助您解决当前的问题。但是,在我看来,您正在创建的内容将是一个非常缓慢,令人困惑且脆弱的测试。现在,您正在嘲笑太多,以致于很难确定您实际要测试的内容。

大量的模拟可能表明您正在测试的代码设计将需要做一些工作以提高可测试性。如果您无法触摸代码,那么您将无法这样做-
但是请尝试使您的测试更具可读性和直观性(“调用此方法时,应该发生此事,因为…”)。



 类似资料:
  • 我有一个类需要测试。以下是的定义: 并根据值从数据库中检索一些要操作的数据。对于该数据库,值通过JSON文件持久化。 这使事情复杂化了。我需要的是在测试时将其设置为某个特定的日期。有没有办法可以用mockito模拟局部变量的值?

  • 有没有可能的方法来模拟一个私人的最终场? 提前谢谢你们。

  • 问题内容: 我有以下要模拟的Logger,但要验证是否正在调用日志条目,而不是内容。 我想模拟用于LoggerFactory.getLogger()的任何类,但是我找不到如何做到这一点。到目前为止,这是我最终得到的结果: 我想知道: 我可以模拟静态模型以用于任何课程吗? 我只能似乎运行的,因此我似乎无法改变每个方法的特点。有没有解决的办法? 编辑结果: 我以为我已经尝试过了,但没有成功: 但是,谢

  • 问题内容: 我试图遵循这个非常相似的问题的答案中提供的示例,但是它对我不起作用。我收到以下错误消息: 我需要一个简单的模拟实例。我不需要模拟任何方法。 这是我要模拟的课程: 我有以下TestNG设置: 问题答案: 我通过扩展PowerMockTestCase类来完成这项工作,该类为TestNG处理此类事情:

  • 我需要卸载一个静态方法 public TestESMock()引发ConfigurationException{ 有人能告诉我怎么做吗。