想要但不要援引:Mockito PrintWriter [英] Wanted but not invoke: Mockito PrintWriter

查看:250
本文介绍了想要但不要援引: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‌​(ProcessImageDataTes‌​t.java:153) 
However, there were other interactions with this mock: -> at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​51) ->  
at  softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​51) -> 
at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​58) –


推荐答案

我在测试中看到3个问题:

I see 3 issues in your test:


  1. 你不喜欢尝试模拟正确的构造函数,确实在方法执行中,创建 PrintWriter 当您尝试使用2个参数模拟构造函数时,使用类型为文件只有一个参数 c $ c>文件和另一个类型字符串

  1. You don't try to mock the correct constructor, indeed in the method execute, you create your PrintWriter with only one argument of type File while you try to mock the constructor with 2 arguments one of type File and the other one of type String.

所以代码应该是:

PowerMockito.whenNew(PrintWriter.class)
    .withArguments(IMAGE_FILE)
    .thenReturn(mockPrintWriter);




  1. 能够模拟一个构造函数你需要准备创建实例的类,在这种情况下是 ProcessImageData ,所以你需要添加 ProcessImageData.class 在注释 @PrepareForTest 中。 (我不确定那里需要 ProcessImageDataTest.class

  1. 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 add ProcessImageData.class in the annotation @PrepareForTest. (I'm not sure ProcessImageDataTest.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆