在这种情况下部分嘲讽有什么问题?
问题描述:
比方说,我有两个方法,其中一个是基本上与额外处理的只是一点点的其它方法的包装:在这种情况下部分嘲讽有什么问题?
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
...
}
}
什么是错编写单元测试删除(UUID)方法部分嘲讽ItemRepositoryImpl,并检查该删除(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上。什么会更好的解决方案?
答
如果你正在做一个纯粹的单元测试,并且你的测试单元是一种方法,那么我会说你在这里嘲笑的东西没有错。有人会认为单元测试应该采取更加黑盒子的方法,并且通过模拟方法调用,测试对测试方法的实现知道太多。
如果被测试的单元是类而不是方法,那么你可以简单地将对其他类的调用模拟。
单元测试总是存在争议。这里有一篇关于这个主题的文章,与你的问题非常相关:http://martinfowler.com/articles/mocksArentStubs.html
虽然它真的是一堆重复测试吗?我想象一下'delete(UUID)'的两个测试 - 其中一个项目被找到,另一个找不到项目。在delete(Item)'的测试中测试调用的'delete(Item)'部分中的任何详细处理。 –