我正在学习TDD,并且在将Mocks与嘲笑和junit一起使用时有一些疑问。
Without mocks:
Contacto contacto = new Contacto("Santiago", "3022653192", "santi-1524@hotmail.com");
agenda.agregarContacto(contacto);
Assert.assertEquals(1, agenda.getSizeOfAgenda());
agenda.agregarContacto(contacto);
With mocks:
Mockito.verify(agenda).agregarContacto(contacto);
Mockito.when(agenda.getSizeOfAgenda()).thenReturn(1);
Assert.assertEquals(1, agenda.getSizeOfAgenda());
如果我不使用模拟程序进行测试,则比使用Test进行测试所需的时间更少:例如2ms与356ms。
在这种情况下,使用Mockito进行测试有什么好处?
答案 0 :(得分:1)
有点缺少嘲讽的要点。您可以使用模拟来确保(模拟)周围服务/外部依赖项以及所有与您要测试的内容无直接关系的行为。
在您的示例中,如果您测试自己的议程服务,则只要contact
进入agenda
,就会嘲笑该联系人与该联系人的内容无关。如果您在calendar
中也说了agenda
,那么您也会嘲笑该calendar
。
在这种情况下,使用Mockito进行测试有什么好处?
在您的情况下,以错误的方式使用了模拟。 一个为什么要进行模拟的清晰示例是一个Service,它将某些内容保存到数据库中。
public class SomeService {
private SomeRepository repo;
public SomeService(SomeRepository repo){
this.repo = repo;
}
public YourClass save(YourClass clazz){
repo.save(clazz);
}
}
public class SomeRepository {
private Connection yourDatabaseConnection;
public YourClass save(YourClass clazz){
yourDatabaseConnection.save(clazz);
}
}
因此,不要打扰如何建立连接。当您从SomeService
运行测试时,这将调用您的存储库,从而将某些内容保存在数据库中。这意味着您将必须建立一个数据库并照顾其中的数据,如果您同时运行多个测试或并行运行测试(如果您和一个学院同时与您进行同一测试),则可能会产生问题。所有这些都是小题大做,超出了单元测试理论的范围。在这种情况下,您的单位就是服务SomeService
。因此,您只需要测试一下。
@Test
public void test(){
final SomeRepository repo = mock(SomeRepository.class);
final SomeService serv = new SomeService(repo);
final YourClass clazz = mock(YourClass.class);
when(repo.save(clazz)).thenReturn(clazz);
YourClass response = serv.save(clazz);
Assert.assertEquals(clazz,response);
verify(repo).save(clazz);
}
这样,您可以验证服务返回的对象,中间没有任何变化,因为这是上述设置的预期行为。您验证它称为存储库,但从未真正调用它。这样,不会在数据库中添加任何数据(这意味着您不需要数据库),并且测试是隔离的,可以并行运行一百万次,并且始终具有相同的结果。