問題描述
我有這樣的場景
InputStreamReader reader = new InputStreamReader(getFileAsStream(resourceResolver, iconpath));
BufferedReader bReader = new BufferedReader(reader);
我一直嘲諷到現在
getFileAsStream(resourceResolver, iconpath)
現在我得到了一位讀者
BufferedReader bReader = new BufferedReader(reader);
但是當我執行這一行時,我得到 null 并且無法繼續前進
but when I execute this line I get null and not able to move forward
while ((iconEntry = bReader.readLine()) != null)
請告訴我如何模擬這個.請注意,我無法更改我的主要代碼,因此 Mockito 文檔中的解決方案在我的情況下無效
Please tell me how can I mock this. Please note I cannot change my main code therefore the solution present on Mockito docs is not valid in my case
測試代碼
@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 來攔截構造函數調用(new InputStreamReader(...), new BufferedReader(...))所以你的模擬得到回報.下面是一個例子.在您的情況下,只需攔截新的 BufferedReader 調用就足夠了.
To make this work, you need to use Powermockito to intercept the constructor calls (new InputStreamReader(...), new BufferedReader(...)) so that your mocks get returned. An example is below. In your case, just intercepting the new BufferedReader call may be enough.
假設以下是您要測試的代碼:
Assume the following is the code you want to test:
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());
}
}
以下測試代碼是如何攔截構造函數調用的示例:
The following test code is an example of how to intercept the constructor calls:
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);
}
}
希望這能幫助您解決眼前的問題.但是,在我看來,您正在創建的將是一個非常緩慢、令人困惑和脆弱的測試.現在,您的嘲笑太多了,以至于很難確定您實際上要測試什么.
This hopefully helps you in your immediate problem. However, it seems to me that what you're creating will be a very slow, confusing and brittle test. Right now, you're mocking so much that it makes very hard to determine what you're actually trying to test.
大量的模擬可能表明您正在測試的代碼的設計需要一些工作來提高可測試性.如果你不能接觸代碼,那么你就不能——但試著讓你的測試更具可讀性和直觀性(當這個方法被調用時,這件事應該發生,因為......").
The high amount of mocking probably indicates that the design of the code you're testing would need some work to improve testability. If you can't touch the code, then you can't - but try to make your test more readable and intuitive ("When this method is invoked, this thing should happen, because...").
這篇關于如何使用 mockito 或 powermock 模擬局部變量的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!