2012-08-24 55 views
2

比方说,我有两个方法,其中一个是基本上与额外处理的只是一点点的其它方法的包装:在这种情况下部分嘲讽有什么问题?

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上。什么会更好的解决方案?

+0

虽然它真的是一堆重复测试吗?我想象一下'delete(UUID)'的两个测试 - 其中一个项目被找到,另一个找不到项目。在delete(Item)'的测试中测试调用的'delete(Item)'部分中的任何详细处理。 –

回答

1

如果你正在做一个纯粹的单元测试,并且你的测试单元是一种方法,那么我会说你在这里嘲笑的东西没有错。有人会认为单元测试应该采取更加黑盒子的方法,并且通过模拟方法调用,测试对测试方法的实现知道太多。

如果被测试的单元是类而不是方法,那么你可以简单地将对其他类的调用模拟。

单元测试总是存在争议。这里有一篇关于这个主题的文章,与你的问题非常相关:http://martinfowler.com/articles/mocksArentStubs.html