Mockowanie a szpiegowanie w fałszywych frameworkach

131

W kpiarskich frameworkach możesz kpić z obiektu lub go szpiegować . Jaka jest różnica między tymi dwoma i kiedy powinienem / powinienem używać jednego nad drugim?

Patrząc na przykład na Mockito , widzę podobne rzeczy przy użyciu szpiegów i kpiny , ale nie jestem pewien, czy istnieje różnica między nimi.

Vivin Paliath
źródło

Odpowiedzi:

157

Mock obiekt całkowicie zastępuje mockowaną klasę, zwracając zapisane lub domyślne wartości. Możesz stworzyć makietę z „powietrza”. To jest najczęściej używane podczas testów jednostkowych.

Podczas szpiegowania bierzesz istniejący obiekt i „zastępujesz” tylko niektóre metody. Jest to przydatne, gdy masz ogromną klasę i chcesz tylko kpić z niektórych metod (częściowe mockowanie). Pozwolę sobie zacytować dokumentację Mockito :

Możesz tworzyć szpiegów prawdziwych obiektów. Kiedy używasz szpiega, wtedy wywoływane są prawdziwe metody (chyba że metoda została zablokowana).

Prawdziwych szpiegów należy używać ostrożnie i okazjonalnie , na przykład podczas korzystania ze starszego kodu.

W razie wątpliwości używaj prób.

Tomasz Nurkiewicz
źródło
1
Dziękuję Ci! To sprawia, że ​​jest znacznie jaśniejszy. Tak więc kpiny nigdy nie są delegowane na rzeczywisty obiekt, z którego kiedykolwiek kpiono , ale robią to szpiedzy.
Vivin Paliath
7
Makiety nie mają „rzeczywistego obiektu” - makieta jest tworzona ab initio.
Carl Manaster
4
Jakieś wyjaśnienie, dlaczego Mockito ostrzega przed wykorzystywaniem szpiegów przez cały czas? Widzę, że mówią, że faworyzują kpiny, ale nie wiem, dlaczego.
Matt
9
Nie jestem pewien, ale może dlatego, że to „Mockito”, a nie „Spyito”: D
typoerrpr
16

Mockito ostrzega, że ​​częściowe mockowanie nie jest dobrą praktyką i powinieneś zrewidować swoją architekturę zorientowaną obiektowo. Do testowania starszego kodu zaleca się szpiegowanie (lub częściowe mockowanie) .

Suelmar Zanetti
źródło
16

Spróbuję wyjaśnić na przykładzie tutaj:

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

Tutaj mieliśmy początkowy rzeczywisty obiekt list, w którym dodaliśmy jeden element i oczekiwaliśmy jednego rozmiaru.

My spy obiektu rzeczywistego znaczenia, że możemy pouczać, która metoda być zgaszone . Więc zadeklarowaliśmy, że mamy metodę - size()na obiekcie szpiegowskim, który zwróci 10, bez względu na rzeczywisty rozmiar.

Krótko mówiąc, będziesz szpiegować rzeczywisty obiekt i usuwać niektóre z metod .

user2775185
źródło
2

Źródła : http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

W przypadku używania obiektów pozorowanych domyślne zachowanie metody, gdy nie jest to skrót, to nic nie rób. Proste oznacza, że ​​jeśli jest to metoda void, to nic nie zrobi, gdy wywołasz metodę lub jeśli jest to metoda z wartością zwrotną, może zwrócić wartość null, pustą lub domyślną.

Oczywiście w przypadku obiektów szpiegowskich, ponieważ jest to prawdziwa metoda, kiedy nie blokujesz metody, wywoła ona prawdziwe zachowanie metody. Jeśli chcesz zmienić i kpić z metody, musisz ją zablokować.

Jerry C.
źródło
2

Atrapy są przekazywane dookoła, ale w rzeczywistości nigdy nie są używane. Zwykle służą do wypełniania list parametrów.

Fałszywe obiekty faktycznie mają działające implementacje, ale zwykle wymagają pewnych skrótów, co sprawia, że ​​nie nadają się do produkcji (dobrym przykładem jest baza danych w pamięci).

Stuby zapewniają gotowe odpowiedzi na połączenia wykonane podczas testu, zwykle nie odpowiadają w ogóle na nic poza tym, co jest zaprogramowane w teście.

Szpiedzy to kody, które również rejestrują pewne informacje na podstawie ich wywołania. Jedną z form może być usługa e-mail, która rejestruje liczbę wysłanych wiadomości.

Mocks są tym, co mówimy o tutaj: Przedmioty z zaprogramowanymi oczekiwań stanowiących specyfikację połączeń oczekuje oni otrzymać.

Mocks Aren't Stubs autorstwa Martina Fowlera

Mohsen
źródło
1

Szpiedzy mają dwie definicje. Pierwsza polega na tym, że wywoływana jest prawdziwa metoda, a druga, gdzie nie jest wywoływana żadna funkcjonalność i zwracane są tylko wartości null lub null równoważne, ale metody zostały wywołane, a ich stan został zarejestrowany, zwykle tak, jak metoda x została wywołana y razy.

John Heilman
źródło
0

W Mockito, jeśli przypiszesz dowolny obiekt do zmiennej instancji Mock Object, nie ma to wpływu na Mock Object.

Ale w przypadku Szpiega, jeśli przypiszesz jakikolwiek obiekt do zmiennej instancji Obiektu Szpiega, wpłynie to na Obiekt Szpiega, ponieważ Szpieg działa jak modyfikacja obiektu w czasie rzeczywistym.

Jako przykład odniesienia są

@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));
    }
}
Yasir Shabbir Choudhary
źródło