模拟框架中的模拟与间谍

Viv*_*ath 114 tdd unit-testing mocking

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

Tom*_*icz 132

模拟对象完全替换模拟类,返回记录或默认值.你可以用"稀薄的空气"创造模拟.这是在单元测试期间主要使用的.

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

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

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

如有疑问,请使用嘲笑.

  • 模拟没有"实际对象" - 模拟是从头开始创建的. (6认同)
  • 我不确定,但也许是因为他们是"Mockito"而不是"Spyito":D (6认同)
  • Mockito为什么一直警告不要使用间谍的任何解释?我看到他们说要赞成嘲笑,但我不清楚原因. (3认同)

Moh*_*sen 20

基于Martin Fowler《模拟不是存根》:

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

对象实际上有工作实现,但通常采取一些捷径,这使得它们不适合生产(内存数据库就是一个很好的例子)。

存根为测试期间拨打的电话提供预设答案,通常根本不响应测试编程之外的任何内容。

间谍是存根,还根据其被调用方式记录一些信息。其中一种形式可能是记录发送的消息数量的电子邮件服务。

模拟就是我们在这里讨论的:用期望预先编程的对象,形成它们期望接收的调用的规范。


小智 10

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

  • 希望你意识到这是一个评论(我知道你还不能发表评论). (3认同)

use*_*185 10

可以尝试用这里的例子来解释.

// difference between mocking, stubbing and spying
@Test
public void differenceBetweenMockingSpyingAndStubbing(){
    List list = new ArrayList();
    list.add("abc");
    assertEquals(1,list.size());
    List mockedList = spy(list);
    when(mockedList.size()).thenReturn(10);
    assertEquals(10,mockedList.size());
}
Run Code Online (Sandbox Code Playgroud)

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

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

简而言之,你将窥探真实对象和存根的一些方法.


Yas*_*ary 5

在 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));
    }
}
Run Code Online (Sandbox Code Playgroud)