模拟框架中的模拟与间谍

时间:2012-10-10 20:14:17

标签: unit-testing mocking tdd

在模拟框架中,您可以模拟对象或监视它。这两者之间有什么区别?我应该/何时使用一个而不是另一个?例如,看看mockito,我看到使用间谍和嘲讽做类似的事情,但我不确定两者之间的区别。

7 个答案:

答案 0 :(得分:129)

模拟对象完全替换模拟类,返回记录或默认值。你可以用“稀薄的空气”创造模拟。这是在单元测试中最常用的。

当进行间谍活动时,您将获取现有对象并仅“替换”某些方法。当你有一个庞大的类并且只想模拟某些方法(部分模拟)时,这很有用。让我引用Mockito documentation

  

您可以创建真实对象的间谍。当你使用间谍时,会调用真正的方法(除非方法被存根)。

     

真正的间谍应该谨慎使用,例如在处理遗留代码时。

如有疑问,请使用嘲笑。

答案 1 :(得分:9)

Mockito警告说,部分嘲笑不是一个好习惯,你应该修改你的OO架构。建议使用间谍(或部分模拟)来测试遗留代码。

答案 2 :(得分:8)

可以尝试使用此处的示例进行解释。

bigLists = ([z.strip('[').strip(']') for z in y.split('\n') if z]
            for y in x.split('\n\n'))

bigListA = [x for x in bigLists if x[0] == 'Blocktype A']
bigListB = [x for x in bigLists if x[0] == 'Blocktype B']

在这里,我们有了初始的真实对象列表,其中我们添加了一个元素,预期大小为1。

我们窥探真实对象意味着我们可以指示哪个方法被存根。所以我们声明我们在spy对象上存在方法 - size(),它将返回10,无论实际大小是多少。

简而言之,你将窥探真实对象并存根一些方法。

答案 3 :(得分:1)

间谍有两个定义。一个是调用真实方法的地方,另一个是调用没有功能的函数,只返回null或null等效值,但是调用了方法,并且记录了状态,通常类似于方法x被称为y次。

答案 4 :(得分:1)

参考:http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

使用模拟对象时,方法的默认行为不是stub时什么也不做。简单的意思是,如果它是一个void方法,那么当你调用该方法时它将什么都不做,或者如果它的方法带有return,那么它可能返回null,empty或默认值。

当然,在间谍对象中,因为它是一种真正的方法,当你没有对方法进行存根时,它会调用真正的方法行为。如果要更改并模拟方法,则需要将其存根。

答案 5 :(得分:0)

在Mockito中,如果将任何对象分配给Mock Object的实例变量,则不会影响Mock Object。

但是对于Spy,如果将任何对象分配给Spy Object的实例变量,则确实会影响Spy Object,因为Spy就像实时对象修改一样。

参考示例为

@RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {

    @Mock
    private List<String> mockList;

    @Spy
    private List<String> spyList = new ArrayList();

    @Test
    public void testMockList() {
        //by default, calling the methods of mock object will do nothing
        mockList.add("test");
        assertNull(mockList.get(0));
    }

    @Test
    public void testSpyList() {
        //spy object will call the real method when not stub
        spyList.add("test");
        assertEquals("test", spyList.get(0));
    }
}

答案 6 :(得分:0)

  

虚拟对象被传递但从未实际使用过。通常它们只是用来填充参数列表。

     

伪造对象实际上具有有效的实现,但是通常采用一些捷径,这使其不适合生产(内存数据库是一个很好的示例)。

     

存根为测试期间进行的通话提供固定答案,通常不会对测试中编程的内容完全响应。

     

间谍是存根,它们还会根据调用方式记录一些信息。其中一种形式可能是电子邮件服务,它记录发送了多少消息。

     

模拟是我们在这里所说的:预先编程并带有期望的对象,这些对象构成了期望接收的呼叫的规范。

Mocks Aren't Stubs by Martin Fowler