different types matchers provided mockito
software di ottimizzazione gratuito per Windows 7
Un'introduzione ai diversi tipi di matcher in Mockito.
Scherzi e spie a Mockito sono stati spiegati in dettaglio nel nostro precedente tutorial di dettagliate Serie di allenamento Mockito .
Cosa sono i Matcher?
I matcher sono come espressioni regolari o caratteri jolly in cui invece di un input (e / o output) specifico, specifichi un intervallo / tipo di input / output in base al quale possono essere riposati gli stub / spie e le chiamate agli stub possono essere verificate.
Tutti gli abbinatori Mockito fanno parte di ‘ Mockito ' classe statica.
I matcher sono uno strumento potente, che consente un modo abbreviato di impostare stub e di verificare invocazioni sugli stub citando gli input degli argomenti come tipi generici per valori specifici a seconda del caso d'uso o dello scenario.
Cosa imparerai:
Tipi di fiammiferi in Mockito
Ci sono sostanzialmente 2 tipi di matcher in Mockito o in termini di utilizzo, i matcher possono essere utilizzati per le seguenti 2 categorie:
- Argument Matchers durante la configurazione dello stub
- Corrispondenze di verifica per la verifica delle chiamate effettive agli stub
Per entrambi i tipi di abbinamenti, ovvero Argomento e Verifica, Mockito fornisce una vasta gamma di abbinamenti (Fare clic su Qui per ottenere un elenco completo dei matchers).
Argument Matchers
Di seguito sono elencati quelli più utilizzati:
Per tutto quanto riportato di seguito, prendiamo in considerazione la possibilità di testare un IntegerList:
final List mockedIntList = mock(ArrayList.class);
# 1) any () - Accetta qualsiasi oggetto (incluso null).
when (mockedIntList.get( any ())).thenReturn(3);
#Due) any (java language class) -
Esempio : any (ClassUnderTest.class) - Questa è una variante più specifica di any () e accetterà solo oggetti del tipo di classe menzionato come parametro del modello.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
# 3) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () e molti altri - Tutti questi accettano qualsiasi oggetto del tipo di dati corrispondente così come valori nulli.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) Argomenti specifici: nei casi in cui gli argomenti effettivi sono noti in anticipo, è sempre consigliabile utilizzarli in quanto forniscono maggiore sicurezza rispetto ai tipi di argomenti generici.
Esempio:
when(mockedIntList.get(1)).thenReturn(3);
Matcher di verifica
Ci sono alcuni matcher specializzati che sono disponibili per aspettarsi / affermare cose come no. di invocazioni sulla finta.
Per tutti i matcher di seguito, consideriamo lo stesso elenco di esempi che abbiamo utilizzato in precedenza.
final List mockedIntList = mock(ArrayList.class);
# 1) Invocazioni fittizie
(io) La semplice invocazione su Mock verifica se il metodo deriso è stato chiamato / interagito o meno impostando la dimensione dell'elenco deriso su 5.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) Il conteggio specifico delle interazioni con un metodo deriso verifica il conteggio di n. di volte ci si aspettava che la finta fosse chiamata.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
Per verificare 0 interazioni, cambia semplicemente il valore da 1 a 0 come argomento per times () matcher.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
In caso di guasti, restituisce le seguenti eccezioni:
per) Quando le chiamate previste sono inferiori alle chiamate effettive:
Esempio: Voluto 2 volte, ma invocato 3 volte, poi Mockito ritorna - ' verifica.TooManyActualInvocations '
Codice di esempio:
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(2)).get(anyInt());
b) Quando le chiamate previste sono più delle chiamate effettive:
come si apre un file json
Esempio: Voluto 2 volte, ma invocato 1 volta, poi Mockito ritorna - ' verifica.TooLittleActualInvocations '
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(4)).get(anyInt());
(iii) Nessuna interazione con il metodo specifico dell'oggetto deriso.
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); // Assert verify(mockedIntList, never()).size();
(iv) Verificare l'ordine delle interazioni fittizie: è particolarmente utile quando si desidera garantire l'ordine in cui sono stati chiamati i metodi sugli oggetti falsificati.
Esempio: Operazioni simili a database in cui un test dovrebbe verificare l'ordine in cui sono avvenuti gli aggiornamenti del database.
Per illustrare questo con l'esempio - Continuiamo con lo stesso elenco di esempi.
Supponiamo ora che l'ordine delle chiamate ai metodi list fosse in sequenza, ovvero get (5), size (), get (2). Quindi, anche l'ordine di verifica dovrebbe essere lo stesso.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size(); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt());
In caso di sequenza di verifica errata, Mockito lancia un'eccezione, ovvero ' verifica.VerificationInOrderFailure '.
Quindi, nell'esempio sopra, se cambio l'ordine di verifica scambiando le ultime 2 righe, inizierò a ricevere l'eccezione VerificationInOrderFailure.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size();
(v) Verificare che l'interazione si sia verificata almeno il numero di volte.
(per) almeno:
Esempio: atleast (3) - Verifica che l'oggetto deriso sia stato invocato / interagito con almeno tre volte durante il test. Quindi qualsiasi interazione 3 o maggiore di 3 dovrebbe rendere la verifica corretta.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atLeast(2)).get(anyInt());
In caso di errori, ad esempio quando le chiamate effettive non corrispondono, viene generata la stessa eccezione del matcher times (), ovvero ' verifica.TooLittleActualInvocations '
(b) al massimo:
Esempio: atmost (3) - verifica se l'oggetto deriso è stato invocato / interagito con atmost tre volte durante il test. Quindi qualsiasi interazione tra 0,1,2 o 3 con il mock dovrebbe rendere la verifica riuscita.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atMost(2)).get(anyInt()); verify(mockedIntList, atMost(2)).size();
# 2) Corrispondenza degli argomenti
Nell'invocazione precedente, i matcher possono essere combinati insieme agli argomenti matchers per convalidare gli argomenti con cui è stato chiamato il mock.
- qualunque()
- Valori specifici: verifica con i valori specifici quando gli argomenti sono noti in anticipo.
- Altri abbinatori di argomenti come - anyInt (), anyString () ecc.
Suggerimenti e trucchi
# 1) Utilizzo di Argument Capture durante la verifica
La verifica di Argument Capture è in genere utile quando l'argomento utilizzato da un metodo stubbed non viene passato direttamente tramite una chiamata al metodo ma viene creato internamente quando viene chiamato il metodo sottoposto a test.
Questo è essenzialmente utile quando il tuo metodo dipende da uno o più collaboratori il cui comportamento è stato bloccato. Gli argomenti passati a questi collaboratori sono un oggetto interno o un insieme di argomenti completamente nuovo.
Convalidare l'argomento con cui sarebbero stati chiamati i collaboratori garantisce molta fiducia nel codice che si sta testando.
Mockito fornisce ArgumentCaptor che può essere utilizzato con la verifica e quindi, quando viene chiamato 'AgumentCaptor.getValue ()', possiamo affermare l'argomento effettivamente catturato rispetto a quello previsto.
Per illustrare ciò, fare riferimento all'esempio seguente:
Nel metodo di seguito, calcolarePrice è il modello con la classe InventoryModel creato all'interno del corpo del metodo che viene quindi utilizzato da InventoryService per l'aggiornamento.
Ora, se vuoi scrivere un test per convalidare con quale argomento è stato chiamato l'inventoryService, puoi semplicemente usare l'oggetto ArgumentCaptor di tipo InventoryModel classe.
Metodo in prova:
come aprire un file .apk in Windows
public double calculatePrice(int itemSkuCode) { double price = 0; // get Item details ItemSku sku = itemService.getItemDetails(itemSkuCode); // update item inventory InventoryModel model = new InventoryModel(); model.setItemSku(sku); model.setItemSuppliers(new String(){'Supplier1'}); inventoryService.updateInventory(model, 1); return sku.getPrice(); }
Codice di prova: Guarda il passaggio di verifica in cui viene verificato l'inventarioService, l'oggetto argomentoCaptor viene sostituito per il quale argomento deve essere trovato.
Quindi asserisci semplicemente il valore invocando il metodo getValue () sull'oggetto ArgumentCaptor.
Esempio: ArgumentCaptorObject.getValue ()
public void calculatePrice_withValidItemSku_returnsSuccess() { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); CustomerProfile customerProfile = new CustomerProfile(); customerProfile.setExtraLoyaltyDiscountPercentage(2.00); double expectedPrice = 93.00; // Arrange when(mockedItemService.getItemDetails(anyInt())).thenReturn(item1); ArgumentCaptor argCaptorInventoryModel = ArgumentCaptor.forClass(InventoryModel.class); // Act priceCalculator.calculatePrice(1234); // Assert verify(mockedItemService).getItemDetails(anyInt()); verify(mockedInventoryService).updateInventory(argCaptorInventoryModel.capture(), eq(1)); assertEquals(argCaptorInventoryModel.getValue().itemSku, item1);
Senza ArgumentCaptor non ci sarebbe modo di identificare con quale argomento è stata effettuata la chiamata di servizio. La cosa migliore possibile è utilizzare 'any ()' o 'any (InventoryModel.class)' per verificare gli argomenti.
# 2) Eccezioni / errori comuni durante l'utilizzo di Matcher
Durante l'utilizzo di Matcher, ci sono alcune convenzioni che dovrebbero essere seguite, che se non seguite, si traduce in un'eccezione che viene generata. Il più comune in cui mi sono imbattuto è durante lo stubbing e la verifica.
Se stai usando un parametro Matcher e se il metodo stubbed ha più di uno o più argomenti, allora tutti gli argomenti dovrebbero essere menzionati con i matchers, altrimenti nessuno di loro dovrebbe avere dei matchers. Ora, cosa significa questo?
Proviamo a capirlo con uno scenario (e poi un esempio di codice per questo scenario)
- Supponiamo che il metodo sotto test abbia una firma come -
concatenateString (String arg1, String arg2) - Ora, quando esegui lo stubbing, supponi di conoscere il valore di arg1, ma arg2 è sconosciuto, quindi decidi di utilizzare un abbinamento di argomenti come - any () o anyString () e di specificare un valore per il primo argomento come un testo 'ciao'.
- Quando il passaggio precedente viene implementato e il test viene eseguito, il test genera un'eccezione chiamata 'InvalidUseOfMatchersException'
Proviamo a capirlo con un esempio:
Codice di prova:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
Classe in prova:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
Quando viene eseguito il test di cui sopra, ritorna in ' InvalidUseOfMatchersException '
Qual è il motivo di questa eccezione?
È lo stubbing che utilizza corrispondenze di parti e stringhe fisse, ovvero abbiamo menzionato un abbinamento di argomenti come 'ciao' e il secondo come anyString (). Ora ci sono 2 modi per sbarazzarsi di questo tipo di eccezioni (Nota anche che questo comportamento si applica sia alle configurazioni Mock che al comportamento).
# 1) Usa gli Argument Matchers per tutti gli argomenti:
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) Usa eq () come Argument Matcher dove l'argomento è noto. Quindi, invece di specificare l'argomento come 'ciao', specificalo come 'eq (' ciao ') e questo dovrebbe rendere lo stubbing corretto.
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
Conclusione
In questo articolo abbiamo visto come utilizzare diversi tipi di matcher forniti da Mockito.
Qui, abbiamo coperto quelli più utilizzati. Per fare riferimento all'elenco completo, la documentazione della libreria Mockito è una buona fonte di riferimento.
Dai un'occhiata al nostro prossimo tutorial per saperne di più sui metodi di derisione privati, statici e nulli.
Tutorial PREV | PROSSIMO Tutorial
Lettura consigliata
- Creazione di mock e spie in Mockito con esempi di codice
- Tutorial Mockito: Mockito Framework per Mocking in Unit Testing
- Tipi di rischi nei progetti software
- Tipi di dati Python
- Tipi di dati C ++
- Le 12 migliori domande per l'intervista Mockito (Intervista sul quadro beffardo)
- Mocking metodi privati, statici e nulli utilizzando Mockito
- Tipi di ereditarietà in C ++