2016-10-21 41 views
1

嗨我正在一个项目和使用PrintWriter类打开和写入文件。但是,当我在为同一写测试用例它给了以下错误在线路153想要但不是援引:Mockito PrintWriter

Wanted but not invoked: 
    mockPrintWriter.println("ID url1 
    "); 
-> at x.y.z.verify(ProcessImageDataTest.java:153) 
Actually, there were zero interactions with this mock. 

代码:(使用龙目岛库)

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

@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的运算符也是使用beans注入的。我在做什么错误?我很久没有接受这个错误了吗? 任何帮助表示赞赏。

更新

我建议以下变化和更新的代码,但现在我得到的错误:

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) – 
+1

尽量不要隐瞒留下了'捕获任何异常'子句为空。你能包括一张印刷品或其中的东西吗? – SomeJavaGuy

+0

请注意'lineIterator'上缺少'@ Mock'。相反,要用新行验证'print',尝试验证'println'没有新行,它不太容易出错,并告诉我它是否有帮助 –

回答

1

我看到在您的测试3个问题:

  1. 你不要试图嘲笑正确的构造,确实是在方法execute,创建您PrintWriter只有一个File类型的参数而您尝试模拟构造函数与2个参数类型FileString类型中的另一个。

因此,代码而应是:

PowerMockito.whenNew(PrintWriter.class) 
    .withArguments(IMAGE_FILE) 
    .thenReturn(mockPrintWriter); 
  • 为了能够嘲笑你需要准备的类创建它是实例的构造在这种情况下为ProcessImageData,所以您需要在注释@PrepareForTest中添加ProcessImageData.class。(我不确定那里需要ProcessImageDataTest.class

  • 该字段lineIterator应注明@Mock

  • 而是用一个新行验证print的,应当验证直接println没有新线它是非常不容易出错。


  • 我简化你的代码显示的想法。

    假设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"); 
        } 
    } 
    

    欲了解更多详情,请参阅How to mock construction of new objects


    how can I add verification in unit test for writer.close?

    的一种方法是简单地检查close()在被调用一次加入下一行到你的单元测试:

    Mockito.verify(mockPrintWriter, Mockito.times(1)).close(); 
    
    +0

    嘿谢谢。这工作。但它显示另一个错误: 通缉但未调用: mockPrintWriter.print(“ASIN2 url1 ”); - >在softlines.ctl.ruleExecutor.tasks.ProcessImageDataTest.verify(ProcessImageDataTest.java:153) 然而,有与该模拟的其它交互: - 在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) – user2696258

    +0

    我已经更新了这个问题。你能否说出为什么特定的模拟交互没有被调用。 – user2696258

    +1

    是的,谢谢它的工作。删除换行工作! – user2696258

    0

    你的PrintWriter的施工模拟不匹配。你告诉PowerMockito来回报您的模拟像这样:

    PowerMockito.whenNew(PrintWriter.class).withArguments(IMAGE_FILE , StandardCharsets.UTF_8.name()).thenReturn(mockPrintWriter); 
    

    所以,你不得不说:

    new PrintWriter(IMAGE_FILE, "UTF-8"); // 2 arguments 
    

    但不是在被测试的代码你execute方法,你这样做:

    PrintWriter writer = new PrintWriter(newImageDataTextFile); // only 1 argument 
    

    因此,您需要更改PowerMockito withArguments子句,或者您需要将"UTF-8"添加到中的构造函数调用中方法。