私はMockitoを初めて使っています。 getAllFoo()
メソッドのすべてのブランチをテストするために、私のテストクラスにMockitoのAnswer
インターフェイスを使用しようとしています。私はisFooComplete()
をfalse
に戻して最初の2回呼び出すと、actualFoo
にのオブジェクトが含まれているので、テストの最後にtrue
を返します。メソッドのすべてのブランチをテストするためのMockitoの回答インタフェースの実装
問題は、私はservice
にgetAllFoo()
を呼んでいるループのために、false
が最初に返された内側(あなたがgetAllFoo()
メソッドの実装を見て予想通り)、そして、テストは無限ループに陥ってしまうということです。
getAllFoo()
がfalse
を2回返すようにこのテストを変更してから、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;
}
}
Testクラス:
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());
}
}
大漁:
おそらくあなたはこれをやりたいです。私はそれを増やすように編集しました。 最初に私のコードで間違ってコピーしました: 'service.getAllFoo()'はループ内にあったはずです(これも編集しました)。これが問題を作り出しています:最初の呼び出しはfalseを返し、無限ループでカウンタがインクリメントして最終的に真を返すことができます。 Answerの代わりに 'thenReturn(false、false、true)'を使ってあなたの提案を試みましたが、それでも問題は解決しません。他のアイデア? –