Мокинг против шпионажа в фреймворках имитации


131

В фреймворках имитации вы можете имитировать объект или шпионить за ним. В чем разница между ними и когда я должен / должен использовать одно вместо другого?

Глядя на Mockito , например, я вижу, что похожие вещи делаются с использованием шпионов и имитаторов , но я не уверен в различии между ними.



Ответы:


157

Мок-объект полностью заменяет фиктивный класс, возвращая записанные или значения по умолчанию. Вы можете создать макет «из воздуха». Это то, что в основном используется во время модульного тестирования.

При шпионаже вы берете существующий объект и «заменяете» только некоторые методы. Это полезно, когда у вас огромный класс и вы хотите имитировать только определенные методы (частичное имитирование). Позвольте процитировать документацию Mockito :

Вы можете создавать шпионов из реальных объектов. Когда вы используете шпион, вызываются настоящие методы (если метод не был заглушен).

Настоящих шпионов следует использовать осторожно и время от времени , например, при работе с устаревшим кодом.

Если сомневаетесь, используйте моки.


1
Спасибо! Это делает его намного понятнее. Так издевается никогда не делегируют реальный объект осмеиваемые никогда , но шпионы делают.
Вивин Палиат

7
У моков нет «реального объекта» - макет создается ab initio.
Карл Манастер

4
Есть ли объяснение, почему Mockito постоянно предостерегает от использования шпионов? Я вижу, что они говорят в пользу издевательств, но я не понимаю, почему.
Мэтт

9
Я не уверен, но, может быть, потому, что они "Mockito", а не "Spyito": D
typoerrpr

16

Mockito предупреждает, что частичное издевательство не является хорошей практикой, и вам следует пересмотреть свою объектно-ориентированную архитектуру. Для тестирования устаревшего кода рекомендуется использовать шпион (или частичное издевательство) .


16

Я попытаюсь объяснить здесь на примере:

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

Здесь у нас был исходный реальный объект list, в который мы добавили один элемент и ожидали, что размер будет единым.

Мы шпионим за реальным объектом, что означает, что мы можем указать, какой метод заглушить . Так что мы объявили , что мы погасили метод - size()на объекте шпиона , который будет возвращать 10, независимо от того , что фактического размера.

В двух словах, вы будете шпионить реальный объект и незавершенные некоторые из методов .


2

Ссылка: http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

При использовании фиктивных объектов поведение метода по умолчанию, когда он не заглушен, - ничего не делать. Простое означает, что если это метод void, он ничего не будет делать, когда вы вызываете метод, или если это метод с возвратом, он может вернуть значение null, empty или значение по умолчанию.

Конечно, в объектах-шпионах, поскольку это настоящий метод, когда вы не заглушаете метод, он вызывает реальное поведение метода. Если вы хотите изменить и поиздеваться над методом, вам нужно его заглушить.


2

Фиктивные объекты передаются, но на самом деле никогда не используются. Обычно они используются только для заполнения списков параметров.

Поддельные объекты на самом деле имеют работающие реализации, но обычно требуют некоторого сокращения, что делает их непригодными для производства (хорошим примером является база данных в памяти).

Заглушки предоставляют стандартные ответы на звонки, сделанные во время теста, обычно не отвечая ни на что, кроме того, что запрограммировано для теста.

Шпионы - это заглушки, которые также записывают некоторую информацию в зависимости от того, как они были вызваны. Одной из форм этого может быть служба электронной почты, которая записывает, сколько сообщений было отправлено.

Мы говорим здесь о макетах : объекты, заранее запрограммированные с ожиданиями, которые формируют спецификацию вызовов, которые они ожидают получить.

Моки - это не заглушки, Мартин Фаулер


1

У шпионов есть два определения. В первом случае вызывается реальный метод, в другом - не вызываются функциональные возможности и возвращаются только нулевые или нулевые эквивалентные значения, но методы были вызваны, и их состояние было записано, как правило, метод x был вызван y раз.


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));
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.