如果它很复杂,可能是因为你的班级有不止一个责任。通常,当您拥有执行不同操作的私有方法时,您可以拥有不同的类和为您执行此操作的公共方法。您的课程将变得更易于阅读、测试,并且您将分担责任。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 Mockito