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

我有这样的情况

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);

}

}

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

大量的模拟可能表明您正在测试的代码设计将需要做一些工作以提高可测试性。如果您无法触摸代码,那么您将无法这样做-

但是请尝试使您的测试更具可读性和直观性(“调用此方法时,应该发生此事,因为…”)。

以上是 如何使用Mockito或Powermock模拟局部变量 的全部内容, 来源链接: utcz.com/qa/435342.html

回到顶部