繁体   English   中英

Mocking 与 mocking 框架中的间谍活动

[英]Mocking vs. Spying in mocking frameworks

在 mocking 框架中,您可以模拟object 或监视它。 两者之间有什么区别,我什么时候/应该使用其中一个?

例如,查看Mockito ,我看到类似的事情正在使用spiesmocks完成,但我不确定两者之间的区别。

模拟 object 完全替换模拟的 class,返回记录值或默认值。 您可以“凭空”创建模拟。 这是单元测试期间最常用的。

监视时,您使用现有的 object 并仅“替换”某些方法。 当您有一个巨大的 class 并且只想模拟某些方法(部分模拟)时,这很有用。 让我引用Mockito 文档

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

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

如有疑问,请使用模拟。

我将尝试在这里使用示例进行解释:

// 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());
}

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

我们监视真正的 object 意味着我们可以指示要存根的方法。 所以我们声明我们在spy object上存根方法 - size() ,无论实际大小是多少,它都会返回 10。

简而言之,您将窥探真正的 object存根其中的一些方法

Mockito 警告部分 mocking 不是一个好的做法,您应该修改您的 Object 面向架构。 建议使用间谍(或部分模拟)来测试遗留代码

基于Martin FowlerMocks Aren't Stubs

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

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

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

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

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

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

But in case of Spy, if you assign any object to instance variable of Spy Object then does affect on Spy Object because of Spy act like real-time object modification.

作为参考示例是

@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));
    }
}

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

当使用模拟对象时,方法在非存根时的默认行为是什么都不做。 简单的意思是,如果它是一个 void 方法,那么当你调用该方法时它什么也不做,或者如果它是一个有返回的方法,那么它可能会返回 null、空或默认值。

当然,在 spy 对象中,由于它是一个真实的方法,当您没有对方法进行存根时,它会调用真实的方法行为。 如果要更改和模拟该方法,则需要对它进行存根。

间谍有两个定义。 一个是调用真实方法的地方,另一个是不调用任何功能的地方,仅返回 null 或 null 等效值,但调用了方法,它们是 state 方法,通常记录了 y 次。

如果我们想避免调用外部服务并且只想测试方法内部的逻辑,那么使用模拟。

如果我们想调用外部服务并使用真正的依赖,即按原样运行程序并且只是存根特定的方法,那么使用 spy

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM