2017-02-26 130 views
0

我是Mockito的新手。我試圖在我的測試課程中使用Mockito的Answer界面來測試getAllFoo()方法的所有分支。我想要isFooComplete()返回false前兩次它被調用,然後返回true第三次,以便actualFoo包含2個Foo對象在測試結束。實現Mockito的Answer接口來測試方法的所有分支

的問題是,裏面的for循環在那裏我就打電話servicegetAllFoo(),返回false第一次,然後測試成爲一個無限循環卡(如你所期望看getAllFoo()方法實現)。

如何修改這個測試使getAllFoo()回報false兩次,然後返回true和終止循環?

服務類:

public class ServiceImpl { 

    @Autowired 
    FooService fooService; 

    public Collection<Foo> getAllFoo() { 
     Collection<Foo> allFoo = new ArrayList<>(); 
     boolean complete = fooService.isFooComplete(); 
     boolean available = fooService.isFooAvailable(); 
     while (!complete && available) { 
      Foo foo = fooService.getAvailableFoo(); 
      allFoo.add(foo); 
     } 
     return allFoo; 
    } 
} 

測試類:

public class ServiceImplTest { 

    @InjectMocks 
    ServiceImpl service = new ServiceImpl(); 

    @Mock 
    FooService fooService; 

    class MyAnswer implements Answer<Boolean> { 
     int counter = 0; 

     @Override 
     public Boolean answer(InvocationOnMock inovation) 
      throws Throwable { 
      return (counter++ > 2) ? Boolean.TRUE : Boolean.FALSE; 
     } 
    } 

    @Test 
    public void testGetAllFoo() { 
     MyAnswer myAnswer = new MyAnswer(); 

     MockFoo mockFoo = new MockFoo(); 

     when(fooService.isFooComplete()).thenAnswer(myAnswer); 
     //when(fooService.isFooComplete()).thenReturn(false, false, true); 
     when(fooService.isFooAvailable()).thenReturn(true); 
     when(fooService.getAvailableFoo()).thenReturn(mockFoo); 

     Collection<Foo> actualFoo = new ArrayList<>(); 
     for (int i = 0; i < 3; i++) { 
      actualFoo = service.getAllFoo(); 
     }    
     assertTrue(actualFoo.contains(mockFoo)); 
     assertEquals(2, actualFoo.size()); 
    } 
} 

回答

1

在你的榜樣,你不增加你的櫃檯。所以你的計數器總是0.因此,counter++之前返回並更改您的條件counter >= 2應該做到這一點。

但它看起來像你在這個答案中實現你的FooService邏輯的一部分。我認爲when(fooService.isFooComplete()).thenReturn(true, true, false)可能是更好的選擇。

+0

櫃檯上良好的漁獲物。我已經編輯來增加它。 我在我的代碼中最初做了一個錯誤複製:'service.getAllFoo()'應該在循環內部(我也編輯過) - 這就是創建問題的原因:第一次調用返回false,然後卡住在計數器可以遞增到最終返回true的情況下,在無限循環中。 我試着用'thenReturn(false,false,true)'而不是Answer來解決問題,問題仍然存在。任何其他想法? –

0

你有一個無限循環。 while (!complete && available)將永遠不會完成,因爲完整和可用在while-block內不會更改。

也許你想這樣做:

Collection<Foo> allFoo = new ArrayList<>(); 
boolean complete = fooService.isFooComplete(); 
boolean available = fooService.isFooAvailable(); 
while (!complete && available) { 
    Foo foo = fooService.getAvailableFoo(); 
    allFoo.add(foo); 
    complete = fooService.isFooComplete(); 
    available = fooService.isFooAvailable(); 
} 
+0

看起來似乎是這樣,但實際上'!complete'總是會最終評估爲假,從而脫離循環。面臨的挑戰是讓'fooService.isFooComplete()'在單元測試中嘲弄這種行爲。 –

+0

我不這麼認爲。如果在第一次測試中將完全設置爲false並且可以設置爲true,那麼while循環不會永遠結束!你說**!complete將總是最終評估爲false ** - 但這是不正確的。如果'isFooComplete'將返回false並且'ifFooAvailable'將返回true,那麼while循環將被輸入並且永遠不會離開,因爲兩個變量都不會在循環內改變它們的值,所以循環會一直持續下去。 –

相關問題