假设我有两种方法,其中一种基本上是另一种方法的包装器,只需要一点点额外的处理:
public class ItemRepositoryImpl implements ItemRepository {
...
@Override
public void delete(UUID itemID) {
Item item = findOne(itemID);
delete(item);
}
@Override
public void delete(Item item) {
// Do a bunch of stuff that needs a lot of tests run on it, like
// deleting from multiple data sources etc
...
}
}
为部分抄袭ItemRepositoryImpl的删除(UUID)方法编写单元测试有什么问题,并检查delete(UUID)最终是否调用delete(Item)?如果我这样做,我就不必为每个删除方法写一堆重复的测试!
在Mockito,我可以像这样的间谍实施这样的测试:
ItemRepository spyRepo = spy(repository); // Create the spy
when(spyRepo.findOne(itemID)).thenReturn(item); // Stub the findOne method
doNothing().when(spyRepo).delete(item); // Stub the delete(Item) method
spyRepo.delete(itemID); // Call the method under test
// Verify that the delete(Item) method was called
verify(spyRepo).delete(item);
但是,Mockito文档强烈反对使用这种类型的部分模拟,基本上声明它只应用于临时遗留代码和第三方API。什么是更好的解决方案?
答案 0 :(得分:1)
如果您正在进行纯单元测试并且您的测试单元是一种方法,那么我会说您在这里嘲笑的内容没有任何问题。有些人认为单元测试应采用更黑盒子的方法,并且通过模拟方法调用,您的测试对测试方法的实现了解得太多。
如果您测试的单位是一个类而不是一个方法,那么您可以简单地模拟对其他类的调用。
关于单元测试总是存在争议。这是一篇有关该主题的有趣文章,与您的问题非常相关:http://martinfowler.com/articles/mocksArentStubs.html