複雑な場合は、おそらくクラスに複数の責任があるためです。通常、さまざまなことを行うプライベート メソッドがある場合は、それを行うパブリック メソッドを持つさまざまなクラスを持つことができます。クラスはより読みやすく、テストしやすくなり、責任を分離できます。14 個のプライベート メソッドは通常、この種のことを示します :P
たとえば、次のようなものがあります
public class LeFooService {
private final OtherServiceForConversion barService;
private final FooDao fooDao;
public LeeFooService(FooDao dao, OtherServiceForConversion barService) {
this.barService = barService;
this.fooDao = dao;
}
public void createAsFoo(Bar bar) throws ConversionException {
Foo foo = convert(bar);
fooDao.create(foo);
}
private Foo convert(Bar bar) {
// lots of conversion stuff, services calling D:
}
}
正しくテストするには、変換が正しく行われたかどうかをテストする必要があります。非公開なので、foo
送信先をキャプチャしてFooDao
、すべてのフィールドが正しく設定されているかどうかを確認する必要があります。変換をテストするためにargThat
送信されたものをキャプチャするために使用できます。fooDao
あなたのテストは次のようになります
....
@Test
public void shouldHaveConvertedFooCorrectly() {
// given
Bar bar = mock(Bar.class);
// when
fooService.createAsFoo(bar);
// then
verify(fooDao).create(argThat(fooIsConvertedCorrectly());
}
private ArgumentMatcher<Foo> fooIsConvertedCorrectly() {
return new ArgumentMatcher<Foo>() { /*test stuff*/ };
}
....
ただし、変換を別のクラスに分離すると、次のようになります。
public class LeFooService {
private final BarToFooConverter bar2FooConverter;
private final FooDao fooDao;
public LeeFooService(FooDao dao, BarToFooConverter bar2FooConverter) {
this.bar2FooConverter = bar2FooConverter;
this.fooDao = dao;
}
public void createAsFoo(Bar bar) throws ConversionException {
Foo foo = bar2FooConverter.convert(bar);
fooDao.create(foo);
}
}
LeeFooService にとって本当に重要なこと、つまり呼び出しの流れをテストできます。Foo
からへの変換のテストは、 からの単体テストBar
の責任になりますBarToFooConverter
。LeeFooService のテスト例は次のようになります。
@RunWith(MockitoJUnitRunner.class)
public class LeFooServiceTest {
@Mock
private FooDao fooDao;
@Mock
private BarToFooConverter converter;
@InjectMocks
private LeeFooService service;
@Test(expected = ConversionException.class)
public void shouldForwardConversionException() {
// given
given(converter.convert(Mockito.any(Bar.class))
.willThrown(ConversionException.class);
// when
service.createAsFoo(mock(Bar.class));
// then should have thrown exception
}
@Test
public void shouldCreateConvertedFooAtDatabase() {
// given
Foo convertedFoo = mock(Foo.class);
given(converter.convert(Mockito.any(Bar.class))
.willReturn(convertedFoo);
// when
service.createAsFoo(mock(Bar.class));
// then
verify(fooDao).create(convertedFoo);
}
}
どういうわけか助けてくれることを願っています:)
役に立つかもしれないいくつかのリンク:
個体
BDD モッキート