Подтвердить что ты не робот

Скупой против шпионажа в насмешливых рамках

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

4b9b3361

Ответ 1

Mock object полностью заменяет издеваемый класс, возвращая записанные значения или значения по умолчанию. Вы можете создать макет из "тонкого воздуха". Это то, что в основном используется во время модульного тестирования.

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

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

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

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

Ответ 2

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

Ответ 3

Можно попытаться объяснить здесь пример.

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

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

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

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

Ответ 4

Частичное Mocking может быть достигнуто с использованием как шпиона, так и макета. Для mock мы используем thenCallRealMethod, чтобы вызвать фактический метод, когда шпион по умолчанию вызывает фактический метод. Таким образом, обе достигают одной и той же цели Partical Mocking. Однако рекомендуется использовать Spy для частичного издевательств.

Когда мы используем Mock, фактический экземпляр объекта не создается, но экземпляр оболочки с открытым кодом класса создается для отслеживания взаимодействий. В то время как в случае шпиона мы сами создаем экземпляр объекта, который будет использоваться шпионом. Поэтому использование Mockito Spy гарантирует правильность правильных методов.

Например -

public class EmployeePaymentService {

    EmployeePaymentService(
        final NamedParameterJdbcTemplate namedParameterJdbcTemplate)
        {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
        }

    public int getNoOfWorkingDays(String empId)
    {
        //call some query
        int days=namedParameterJdbcTemplate.query();
            return days;                

    }
}

Если для случая unit test мы частично издеваемся над вышеуказанным EmployeePaymentService, используя Mock as-

@Mock private EmployeePaymentService employeePaymentService;

а затем вызовите фактический метод getNoOfWorkingDays с помощью метода thenCallRealMethod следующим образом:

when(employeePaymentService.getNoOfWorkingDays(anyString())).thenCallRealMethod();                          
int returnedWrkingDays = employeePaymentService.getNoOfWorkingDays(empId);         

Мы получаем java.lang.NullPointerException в методе getNoOfWorkingDays, потому что namedParameterJdbcTemplate никогда не был инициализирован. Однако если мы использовали Mockito Spy, этот сценарий никогда не возникнет, потому что мы сами создали EmployeePaymentService, используя конструктор с именемJdbcTemplate.

Подробнее см. post

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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