我给您两个测试; 目的是仅仅确认当service.doSomething
被调用时,emailService.sendEmail
会以人员的电子邮件作为参数进行调用。
@Mock
private EmailService emailService;
@InjectMocks
private Service service;
@Captor
private ArgumentCaptor<String> stringCaptor;
@Test
public void test_that_when_doSomething_is_called_sendEmail_is_called_NO_MOCKING() {
final String email = "billy.tyne@myspace.com";
// There is only one way of building an Address and it requires all these fields
final Address crowsNest = new Address("334", "Main Street", "Gloucester", "MA", "01930", "USA");
// There is only one way of building a Phone and it requires all these fields
final Phone phone = new Phone("1", "978-281-2965");
// There is only one way of building a Vessel and it requires all these fields
final Vessel andreaGail = new Vessel("Andrea Gail", "Fishing", 92000);
// There is only one way of building a Person and it requires all these fields
final Person captain = new Person("Billy", "Tyne", email, crowsNest, phone, andreaGail);
service.doSomething(captain); // <-- This requires only the person's email to be initialised, it doesn't care about anything else
verify(emailService, times(1)).sendEmail(stringCaptor.capture());
assertThat(stringCaptor.getValue(), eq(email));
}
@Test
public void test_that_when_doSomething_is_called_sendEmail_is_called_WITH_MOCKING() {
final String email = "billy.tyne@myspace.com";
final Person captain = mock(Person.class);
when(captain.getEmail()).thenReturn(email);
service.doSomething(captain); // <-- This requires the person's email to be initialised, it doesn't care about anything else
verify(emailService, times(1)).sendEmail(stringCaptor.capture());
assertThat(stringCaptor.getValue(), eq(email));
}
为什么我的团队告诉我不要模拟运行测试所需的领域对象,而这些对象并非实际测试的一部分?我被告知mock只用于被测试服务的依赖项。我认为,结果的测试代码更简洁、更清晰、更易于理解。没有任何东西会分散对调用
emailService.sendEmail
的验证的注意力,这是测试的目的。这是我长期以来听到和接受的教条之一,在许多工作中都有应用。但我仍然不能同意这种说法。