简体   繁体   English

Mocking 与 mocking 框架中的间谍活动

[英]Mocking vs. Spying in mocking frameworks

In mocking frameworks, you can mock an object or spy on it.在 mocking 框架中,您可以模拟object 或监视它。 What's the difference between the two and when would/should I use one over the other?两者之间有什么区别,我什么时候/应该使用其中一个?

Looking at Mockito , for example, I see similar things being done using spies and mocks , but I am unsure as to the distinction between the two.例如,查看Mockito ,我看到类似的事情正在使用spiesmocks完成,但我不确定两者之间的区别。

Mock object replace mocked class entirely, returning recorded or default values.模拟 object 完全替换模拟的 class,返回记录值或默认值。 You can create mock out of "thin air".您可以“凭空”创建模拟。 This is what is mostly used during unit testing.这是单元测试期间最常用的。

When spying, you take an existing object and "replace" only some methods.监视时,您使用现有的 object 并仅“替换”某些方法。 This is useful when you have a huge class and only want to mock certain methods (partial mocking).当您有一个巨大的 class 并且只想模拟某些方法(部分模拟)时,这很有用。 Let me quote Mockito documentation :让我引用Mockito 文档

You can create spies of real objects.您可以创建真实对象的间谍。 When you use the spy then the real methods are called (unless a method was stubbed).当您使用 spy 时,会调用真正的方法(除非方法被存根)。

Real spies should be used carefully and occasionally , for example when dealing with legacy code.真正的间谍应该小心谨慎地偶尔使用,例如在处理遗留代码时。

When in doubt, use mocks.如有疑问,请使用模拟。

I'll try to explain using an example here:我将尝试在这里使用示例进行解释:

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

Here, we had initial real object list , in which we added one element and expected size to be one.在这里,我们有初始的真实 object list ,我们在其中添加了一个元素,预期大小为 1。

We spy real object meaning that we can instruct which method to be stubbed .我们监视真正的 object 意味着我们可以指示要存根的方法。 So we declared that we stubbed method - size() on spy object which will return 10, no matter what is actual size.所以我们声明我们在spy object上存根方法 - size() ,无论实际大小是多少,它都会返回 10。

In a nutshell, you will spy real object and stub some of the methods .简而言之,您将窥探真正的 object存根其中的一些方法

Mockito warns that partial mocking isn't a good practice and you should revise your Object Oriented architecture. Mockito 警告部分 mocking 不是一个好的做法,您应该修改您的 Object 面向架构。 Spy (or partial mocking) is recommended to test legacy code .建议使用间谍(或部分模拟)来测试遗留代码

Based on Mocks Aren't Stubs by Martin Fowler :基于Martin FowlerMocks Aren't Stubs

Dummy objects are passed around but never actually used.虚拟对象被传递但从未实际使用过。 Usually they are just used to fill parameter lists.通常它们仅用于填充参数列表。

Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).对象实际上有工作实现,但通常采取一些捷径,使它们不适合生产(memory 数据库中的一个很好的例子)。

Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.存根为测试期间拨打的电话提供预设答案,通常根本不响应任何超出测试程序的内容。

Spies are stubs that also record some information based on how they were called.间谍是存根,它还根据调用方式记录一些信息。 One form of this might be an email service that records how many messages it was sent.其中一种形式可能是 email 服务,它记录发送了多少消息。

Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.模拟就是我们在这里讨论的内容:预先编程的对象具有期望,这些期望形成了它们期望接收的调用的规范。

In Mockito if you assign any object to instance variable of Mock Object then does not affect on Mock Object.在 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. 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.

For a reference example are作为参考示例是

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

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

When using mock objects, the default behavior of the method when not stub is do nothing.当使用模拟对象时,方法在非存根时的默认行为是什么都不做。 Simple means, if its a void method, then it will do nothing when you call the method or if its a method with a return then it may return null, empty or the default value.简单的意思是,如果它是一个 void 方法,那么当你调用该方法时它什么也不做,或者如果它是一个有返回的方法,那么它可能会返回 null、空或默认值。

While in spy objects, of course, since it is a real method, when you are not stubbing the method, then it will call the real method behavior.当然,在 spy 对象中,由于它是一个真实的方法,当您没有对方法进行存根时,它会调用真实的方法行为。 If you want to change and mock the method, then you need to stub it.如果要更改和模拟该方法,则需要对它进行存根。

Spies have two definitions.间谍有两个定义。 One, is where the real method is called, another where, no functionality is called and only null or null equivalent values are returned, but methods were called, and they're state was recorded, commonly like, method x was called y times.一个是调用真实方法的地方,另一个是不调用任何功能的地方,仅返回 null 或 null 等效值,但调用了方法,它们是 state 方法,通常记录了 y 次。

If we want to avoid calling external services and just want to test the logic inside the method then use mock.如果我们想避免调用外部服务并且只想测试方法内部的逻辑,那么使用模拟。

If we want to call the external services and use the real dependency ie to run the program as it is and just stub specific methods then use spy如果我们想调用外部服务并使用真正的依赖,即按原样运行程序并且只是存根特定的方法,那么使用 spy

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

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