一段常见的代码
单元测试是项目的重要组成部分。尤其是对持续发展的产品,单元测试在后期的维护,回归有重要等方面有重要作用。
这样代码在项目中随处可见,看看我们应该如何测试
public class NotifyService {
private UserCenter uc;
private MessageCenter mc;
public void sendMessage(long userId, String message) {
String email = uc.getUser(userId).getEmail();
mc.sendEmail(email, message);
}
public void setUc(UserCenter uc) {
this.uc = uc;
}
public void setMc(MessageCenter mc) {
this.mc = mc;
}
}
UserCenter和MessageCenter都是接口,User是一个简单的JavaBean
由于uc和mc乃外部依赖,此类不需也不应保证uc和mc的正确性,此类只需保证:
假设uc和mc是正确的,那么我也是正确的。
所以需要隔离依赖--使用mock
使用Mockito
假使使用Mockito,单元测试也许是这个样子的[需要static import org.mockito.Mockito类的相关方法]
public class NotifyServiceTest {
private NotifyService notifyService;
private UserCenter uc;
private MessageCenter mc;
@Before
public void setUp() {
notifyService = new NotifyService();
uc = mock(UserCenter.class);
mc = mock(MessageCenter.class);
notifyService.setUc(uc);
notifyService.setMc(mc);
}
@Test
public void testSendMessage() {
long userId = 1L;
String email = "foo@bar";
when(uc.getUser(userId)).thenReturn(createUserWithEmail(email));
notifyService.sendMessage(userId, "hello");
verify(mc).sendEmail(eq(email), eq("hello"));
}
private User createUserWithEmail(String email) {
User user = new User();
user.setEmail(email);
return user;
}
}
看到testSendMessage方法
@Test
public void testSendMessage() {
long userId = 1L;
String email = "foo@bar";
when(uc.getUser(userId)).thenReturn(createUserWithEmail(email));
notifyService.sendMessage(userId, "hello");
verify(mc).sendEmail(eq(email), eq("hello"));
}
语义不言自明
测试前,从uc获得email
测试后,必须调用mc.sendEmail,所以验证之
小结
通过一个简单的例子,可以看到:mockito在使我们的测试代码更直接,语义更明确