想要但不要援引:Mockito PrintWriter [英] Wanted but not invoke: Mockito PrintWriter
问题描述
您好我正在开发一个项目并使用 PrintWriter
类来打开和写入文件。但是当我为同样的情况编写测试用例时,它会在第153行给出以下错误
Hi I am working on a project and using PrintWriter
class for opening and writing in the file. But when I am writing the test case for same it gives following error at Line 153
Wanted but not invoked:
mockPrintWriter.println("ID url1
");
-> at x.y.z.verify(ProcessImageDataTest.java:153)
Actually, there were zero interactions with this mock.
代码:(使用龙目岛图书馆)
Code: (Uses Lombok Library)
ProcessImageData.java
ProcessImageData.java
@Setter
@RequiredArgsConstructor
public class ProcessImageData implements T {
private final File newImageDataTextFile;
@Override
public void execute() {
LineIterator inputFileIterator = null;
try {
File filteredImageDataTextFile = new File(filteredImageDataTextFilepath);
PrintWriter writer = new PrintWriter(newImageDataTextFile);
inputFileIterator = FileUtils.lineIterator(filteredImageDataTextFile, StandardCharsets.UTF_8.displayName());
while (inputFileIterator.hasNext()) {
if(someCondition)
**Line51** writer.println(imageDataFileLine);
//FileUtils.writeStringToFile(newImageDataTextFile, imageDataFileLine + NEWLINE, true);
}
}
} catch (Exception e) {
} finally {
LineIterator.closeQuietly(inputFileIterator);
**LINE63** writer.close();
}
}
ProcessImageDataTest.java
ProcessImageDataTest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest({ ProcessImageData.class, FileUtils.class, Printwriter.class })
public class ProcessImageDataTest {
private ProcessImageData processImageData;
private static final String FILTERED_IMAGE_DATA_TEXT_FILE_PATH = "filteredFilepath";
private File FILTEREDFILE = new File(FILTERED_PATH);
private static final File IMAGE__FILE = new File("imageFilePath");
private LineIterator lineIterator;
@Mock
private PrintWriter mockPrintWriter;
@Before
public void init() throws Exception {
MockitoAnnotations.initMocks(this);
processImageData = new ProcessImageData(Palettes_file, FILTERED_PATH, IMAGE_FILE);
PowerMockito.mockStatic(FileUtils.class);
PowerMockito.whenNew(PrintWriter.class).withArguments(IMAGE_FILE).thenReturn(mockPrintWriter);
PowerMockito.when(FileUtils.lineIterator(FILTERED_FILE, StandardCharsets.UTF_8.displayName())).thenReturn(lineIterator);
PowerMockito.when(lineIterator.hasNext()).thenReturn(true, true, false);
}
@Test
public void testTaskWhenIDInDBAndStale() throws IOException {
PowerMockito.when(lineIterator.nextLine()).thenReturn(ID2 + SPACE + URL1, ID1 + SPACE + URL2);
processImageData.execute();
List<String> exepctedFileContentOutput = Arrays.asList(ID2 + SPACE + URL1 + NEWLINE);
verify(exepctedFileContentOutput, 1, 1);
}
@Test
public void testTaskWhenIDNotInDB() throws IOException {
PowerMockito.when(lineIterator.nextLine()).thenReturn(ID2 + SPACE + URL1, ID3 + SPACE + URL2);
processImageData.execute();
List<String> exepctedFileContentOutput = Arrays.asList(ID3 + SPACE + URL2 + NEWLINE);
verify(exepctedFileContentOutput, 1, 1);
}
private void verify(List<String> exepctedFileContentOutput, int fileWriteTimes, int fileReadTimes) throws IOException {
for (String line : exepctedFileContentOutput){
**Line153** Mockito.verify(mockPrintWriter, Mockito.times(fileWriteTimes)).print(line);
}
PowerMockito.verifyStatic(Mockito.times(fileReadTimes));
FileUtils.lineIterator(FILTERED_IMAGE_DATA_TEXT_FILE, StandardCharsets.UTF_8.displayName());
}
}
我正在嘲笑一个新的运营商 PrintWriter
也是,使用bean注入。我在做什么错?很长一段时间我被困在它上面并没有得到错误?
任何帮助都表示赞赏。
I am mocking a new operator for PrintWriter
also, injecting using beans. What is the mistake I am doing?? I am stuck on it from long time and not getting the error?
Any help is appreciated.
更新:
我做过下面建议更改并更新代码,但现在我收到错误:
I did changes suggested below and updated the code, but now I get the error:
Wanted but not invoked: mockPrintWriter.print("ASIN2 url1 "); ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageDataTest.verify(ProcessImageDataTest.java:153)
However, there were other interactions with this mock: -> at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(ProcessImageData.java:51) ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(ProcessImageData.java:51) ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(ProcessImageData.java:58) –
推荐答案
我在测试中看到3个问题:
I see 3 issues in your test:
- 你不喜欢尝试模拟正确的构造函数,确实在方法
执行
中,创建PrintWriter
当您尝试使用2个参数模拟构造函数时,使用类型为文件
的只有一个参数 c $ c>文件和另一个类型字符串
。
- You don't try to mock the correct constructor, indeed in the method
execute
, you create yourPrintWriter
with only one argument of typeFile
while you try to mock the constructor with 2 arguments one of typeFile
and the other one of typeString
.
所以代码应该是:
PowerMockito.whenNew(PrintWriter.class)
.withArguments(IMAGE_FILE)
.thenReturn(mockPrintWriter);
-
能够模拟一个构造函数你需要准备创建实例的类,在这种情况下是
ProcessImageData
,所以你需要添加ProcessImageData.class
在注释@PrepareForTest
中。 (我不确定那里需要ProcessImageDataTest.class
)
To be able to mock a constructor you need to prepare the class creating the instance which is
ProcessImageData
in this case, so you need to addProcessImageData.class
in the annotation@PrepareForTest
. (I'm not sureProcessImageDataTest.class
is needed there)
字段 lineIterator
应使用 @Mock
进行注释。
而不是使用新行验证 print
,您应该直接验证 println
没有新行它是更不容易出错。
Instead of verifying print
with a new line, you should verify directly println
without new line it is much less error prone.
我简化了代码以显示想法。
I simplified your code to show the idea.
假设 ProcessImageData
是:
public class ProcessImageData {
private final File newImageDataTextFile;
public ProcessImageData(final File newImageDataTextFile) {
this.newImageDataTextFile = newImageDataTextFile;
}
public void execute() throws Exception{
try (PrintWriter writer = new PrintWriter(newImageDataTextFile)) {
LineIterator inputFileIterator = FileUtils.lineIterator(
newImageDataTextFile, StandardCharsets.UTF_8.displayName()
);
while (inputFileIterator.hasNext()) {
writer.println(inputFileIterator.nextLine());
}
}
}
}
我的单元测试将是:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ProcessImageData.class, FileUtils.class})
public class ProcessImageDataTest {
private File file = new File("imageFilePath");
private ProcessImageData processImageData;
@Mock
private PrintWriter mockPrintWriter;
@Mock
private LineIterator lineIterator;
@Before
public void init() throws Exception {
MockitoAnnotations.initMocks(this);
processImageData = new ProcessImageData(file);
PowerMockito.whenNew(PrintWriter.class)
.withArguments(file)
.thenReturn(mockPrintWriter);
PowerMockito.mockStatic(FileUtils.class);
PowerMockito.when(
FileUtils.lineIterator(file, StandardCharsets.UTF_8.displayName())
).thenReturn(lineIterator);
PowerMockito.when(lineIterator.hasNext()).thenReturn(true, true, false);
}
@Test
public void testExecute() throws Exception {
PowerMockito.when(lineIterator.nextLine()).thenReturn("Foo", "Bar");
processImageData.execute();
Mockito.verify(mockPrintWriter, Mockito.times(1)).println("Foo");
Mockito.verify(mockPrintWriter, Mockito.times(1)).println("Bar");
}
}
有关详细信息,请参阅 如何模拟新对象的构建 。
For more details please refer to How to mock construction of new objects.
如何在writer.close的单元测试中添加验证?
how can I add verification in unit test for writer.close?
一种方法是简单地检查 close()
是否为通过在单元测试中添加下一行来调用一次:
One way could be to simply check that close()
at be called once by adding the next line to your unit test:
Mockito.verify(mockPrintWriter, Mockito.times(1)).close();
这篇关于想要但不要援引:Mockito PrintWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!