Java PowerkMock ing BufferedReader间歇运行
我想做的是模拟新创建的Java PowerkMock ing BufferedReader间歇运行,java,unit-testing,mocking,powermock,test-double,Java,Unit Testing,Mocking,Powermock,Test Double,我想做的是模拟新创建的BufferedReader实例。下面是应该测试的代码: A.java ... @Override public String read(String fileName) throws IOException { ... try { fileReader = new FileReader(fileName); bufferedReader = new BufferedReader(fileReader); S
BufferedReader
实例。下面是应该测试的代码:
A.java
...
@Override
public String read(String fileName) throws IOException {
...
try {
fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
String tmp;
StringBuilder builder = new StringBuilder();
while ((tmp = bufferedReader.readLine()) != null) {
builder.append(tmp);
}
return builder.toString();
} catch (IOException e) {
...
} finally {
...
}
}
...
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Mock
private FileReader fileReader;
@Mock
private BufferedReader bufferedReader;
...
@Test
public void test() throws Exception {
PowerMockito.whenNew(FileReader.class).withArguments(FILE_NAME).thenReturn(fileReader);
PowerMockito.whenNew(BufferedReader.class).withAnyArguments().thenReturn(bufferedReader);
PowerMockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return "test";
}
}).when(bufferedReader).readLine();
assertArrayEquals(reader.read(FILE_NAME), new String[]{"test"});
}
}
我要做的是,对FileReader
创建和BufferedReader
创建进行PowerMock
ATest.java
...
@Override
public String read(String fileName) throws IOException {
...
try {
fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
String tmp;
StringBuilder builder = new StringBuilder();
while ((tmp = bufferedReader.readLine()) != null) {
builder.append(tmp);
}
return builder.toString();
} catch (IOException e) {
...
} finally {
...
}
}
...
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Mock
private FileReader fileReader;
@Mock
private BufferedReader bufferedReader;
...
@Test
public void test() throws Exception {
PowerMockito.whenNew(FileReader.class).withArguments(FILE_NAME).thenReturn(fileReader);
PowerMockito.whenNew(BufferedReader.class).withAnyArguments().thenReturn(bufferedReader);
PowerMockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return "test";
}
}).when(bufferedReader).readLine();
assertArrayEquals(reader.read(FILE_NAME), new String[]{"test"});
}
}
但测试永远不会结束。我甚至不能调试它
只要删除PowerMockito.doAnswer()
,代码就会被执行(并可用于调试)。我还尝试使用Mockito.mock()
而不是PowerMockito.doAnswer()
,但没有任何帮助
什么可能导致测试的间歇执行?问题是,我还必须在第一个
bufferedReader.readLine()之后模拟值,因为否则它将始终返回模拟值,因此不会终止
Mockito.when(bufferedReader.readLine()).thenReturn("first line").thenReturn(null);
注意
虽然这是问题的实际答案,但是你应该强烈地考虑在另一个答案中选择设计(我最终做到了)。
< P>问题是,在第一个代码> BuffReDeReald.RealLoad()/代码>之后,我还必须模拟值,因为否则它总是返回被嘲弄的值,因此不会终止。
Mockito.when(bufferedReader.readLine()).thenReturn("first line").thenReturn(null);
注意
虽然这是问题的实际答案,但是你应该强烈地考虑在另一个答案中选择设计(我最终做到了)。
< P>只是一个不同的观点:可以说,你的<强>真正的< /强>问题是对FieleRADE/BuffReDeRe读器的两个调用:<代码>新()/代码>。p>
如果您向该方法传递了一个读取器,该怎么办;而不是表示文件名的字符串
如果您将“ReaderFactory”传递给包含此方法的基础类read(String)
,该怎么办?(您将使用依赖项注入将工厂引入类中)
然后:您将看到一个改进的设计,而您不需要使用PowerMock。你可以退后一步,和莫基托或易莫克一起去;因为不再需要模拟调用new
所以,我的答案是:您创建了难以测试的代码。现在,您尝试使用大型(丑陋的)PowerMock hammer修复一个设计问题。是的,那会有用的。但这只是第二个最好的选择
更合理的选择是学习如何编写可测试代码(例如开始);那么,编写可测试代码。停止使用PowerMock(我几个月前就这么做了;在经历了很多PowerMock带来的痛苦之后;我从来没有后悔过这个决定)。只是从另一个角度来看:可以说代码中真正的问题是对FileReader/BufferedReader的new()
的两个调用
如果您向该方法传递了一个读取器,该怎么办;而不是表示文件名的字符串
如果您将“ReaderFactory”传递给包含此方法的基础类read(String)
,该怎么办?(您将使用依赖项注入将工厂引入类中)
然后:您将看到一个改进的设计,而您不需要使用PowerMock。你可以退后一步,和莫基托或易莫克一起去;因为不再需要模拟调用new
所以,我的答案是:您创建了难以测试的代码。现在,您尝试使用大型(丑陋的)PowerMock hammer修复一个设计问题。是的,那会有用的。但这只是第二个最好的选择
更合理的选择是学习如何编写可测试代码(例如开始);那么,编写可测试代码。停止使用PowerMock(我几个月前就这么做了;在经历了很多PowerMock引起的痛苦之后;我从来没有后悔过这个决定)。谢谢,这很有道理。非常欢迎您。当人们回答这样的问题时,我总是很高兴,“但我必须测试的不是我的代码;所以PowerMock是我唯一的选择”——)正如旁注:这里有FileUtilities.readAllLines()-接受一个字符串,并返回该文件中所有行的列表(您可以很容易地找到一个字符串)。因此,也许不必第无数次重新实现“完全读入字符串”,您也可以使用现有无数实现中的一个。我相信ApacheCommons、guava都有这样的方法!谢谢,很有道理。非常欢迎你。当人们回答这样的问题时,我总是很高兴,“但我必须测试的不是我的代码;所以PowerMock是我唯一的选择”——)正如旁注:这里有FileUtilities.readAllLines()-接受一个字符串,并返回该文件中所有行的列表(您可以很容易地找到一个字符串)。因此,也许不必第无数次重新实现“完全读入字符串”,您也可以使用现有无数实现中的一个。我相信ApacheCommons、guava都有这样的方法!