Metodi Mock di Mockito

1. Panoramica

Questo tutorial illustra vari usi dei metodi di simulazione statica standard dell'API Mockito .

Come con altri articoli incentrati sul framework Mockito (come Mockito Verify o Mockito When / Then), la classe MyList mostrata di seguito verrà utilizzata come collaboratore da deridere nei casi di test:

public class MyList extends AbstractList { @Override public String get(int index) { return null; } @Override public int size() { return 1; } }

2. Semplice beffa

La variante sovraccaricata più semplice del metodo mock è quella con un singolo parametro per la classe da deridere :

public static  T mock(Class classToMock)

Useremo questo metodo per deridere una classe e impostare un'aspettativa:

MyList listMock = mock(MyList.class); when(listMock.add(anyString())).thenReturn(false);

Quindi esegui un metodo sul mock:

boolean added = listMock.add(randomAlphabetic(6));

Il codice seguente conferma che il metodo add è stato invocato sul mock e che l'invocazione restituisce un valore che corrisponde all'aspettativa che abbiamo impostato prima:

verify(listMock).add(anyString()); assertThat(added, is(false));

3. Schernire con il nome di Mock

In questa sezione, tratteremo un'altra variante del metodo mock che viene fornito con un argomento che specifica il nome del mock:

public static  T mock(Class classToMock, String name)

In generale, il nome di un mock non ha nulla a che fare con il codice funzionante, ma può essere utile quando si tratta di debug, dove il nome del mock viene utilizzato per rintracciare gli errori di verifica.

Per assicurarci che il nome fornito di un mock sia incluso nel messaggio di un'eccezione generata da una verifica non riuscita, ci baseremo su un'implementazione JUnit dell'interfaccia TestRul e, chiamata ExpectedException , e la includeremo in una classe di test:

@Rule public ExpectedException thrown = ExpectedException.none();

Questa regola verrà utilizzata per gestire le eccezioni generate dai metodi di test.

Nel codice seguente creiamo un mock per la classe MyList e lo chiamiamo myMock :

MyList listMock = mock(MyList.class, "myMock");

Successivamente, imposta un'aspettativa su un metodo del mock ed eseguilo:

when(listMock.add(anyString())).thenReturn(false); listMock.add(randomAlphabetic(6));

Creeremo una verifica intenzionalmente fallita che dovrebbe generare un'eccezione con il messaggio contenente le informazioni sul mock. Per farlo, è necessario prima impostare le aspettative sull'eccezione:

thrown.expect(TooLittleActualInvocations.class); thrown.expectMessage(containsString("myMock.add"));

La seguente verifica dovrebbe fallire e generare un'eccezione corrispondente a quanto previsto:

verify(listMock, times(2)).add(anyString());

Ecco il messaggio dell'eccezione generata:

org.mockito.exceptions.verification.TooLittleActualInvocations: myMock.add(); Wanted 2 times: at com.baeldung.mockito.MockitoMockTest .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...) but was 1 time: at com.baeldung.mockito.MockitoMockTest .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)

Come possiamo vedere, il nome del mock è stato incluso nel messaggio di eccezione, che sarà utile per trovare il punto di errore in caso di verifica non riuscita.

4. Schernendo con risposta

Qui, dimostreremo l'uso di una variante fittizia in cui la strategia per le risposte del mock all'interazione è configurata al momento della creazione. Questo finto firma di metodo nelle Mockito aspetto di documentazione come il seguente:

public static  T mock(Class classToMock, Answer defaultAnswer)

Cominciamo con la definizione di un'implementazione dell'interfaccia Answer :

class CustomAnswer implements Answer { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { return false; } }

La classe CustomAnswer sopra viene utilizzata per la generazione di un mock:

MyList listMock = mock(MyList.class, new CustomAnswer());

If we do not set an expectation on a method, the default answer, which was configured by the CustomAnswer type, will come into play. In order to prove it, we will skip over the expectation setting step and jump to the method execution:

boolean added = listMock.add(randomAlphabetic(6));

The following verification and assertion confirm that the mock method with an Answer argument has worked as expected:

verify(listMock).add(anyString()); assertThat(added, is(false));

5. Mocking With MockSettings

The final mock method that is covered within this article is the variant with a parameter of the MockSettings type. This overloaded method is use to provide a non-standard mock.

There are several custom settings that are supported by methods of the MockSettings interface, such as registering a listener for method invocations on the current mock with invocationListeners, configuring serialization with serializable, specifying the instance to spy on with spiedInstance, configuring Mockito to attempt to use a constructor when instantiating a mock with useConstructor, and some others.

For the convenience, we will reuse the CustomAnswer class introduced in the previous section to create a MockSettings implementation that defines a default answer.

A MockSettings object is instantiated by a factory method as follows:

MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());

Quell'oggetto di impostazione verrà utilizzato nella creazione di un nuovo mock:

MyList listMock = mock(MyList.class, customSettings);

In modo simile alla sezione precedente, invocheremo il metodo add di un'istanza MyList e verificheremo che un metodo mock con un argomento MockSettings funzioni come previsto utilizzando il seguente frammento di codice:

boolean added = listMock.add(randomAlphabetic(6)); verify(listMock).add(anyString()); assertThat(added, is(false));

6. Conclusione

Questo tutorial ha riguardato il finto metodo di Mockito in dettaglio. L'implementazione di questi esempi e frammenti di codice può essere trovata in un progetto GitHub.