Confronto tra Mockito e JMockit: perché Mockito è votato meglio di JMockit?[Chiuso]
-
29-09-2019 - |
Domanda
Sto indagando su quale framework beffardo utilizzare per il mio progetto e ho ristretto il campo JMockit E Mockito.
L'ho notato Mockito è stato votato"il miglior framework fittizio per Java"su StackOverflow.
Confrontando le funzionalità su JMockit'S "Matrice di confronto degli strumenti beffardi" sembra che JMockit ha molteplici caratteristiche diverse.
Qualcuno ha informazioni specifiche (non opinioni) su cosa Mockito può fare ciò che non può essere ottenuto con JMockit e viceversa?
Soluzione
Aggiornamento settembre 2019: L'unica deridevano e sostenuto quadro (per impostazione predefinita) entro la primavera del Boot è Mockito . Se si utilizza Primavera, la risposta è abbastanza ovvia.
Direi che la competizione è tra JMockit e PowerMock , quindi su Mockito .
avrei lasciato "plain" jMock e EasyMock perché usano solo procura & CGLIB e non usano Java 5 strumentazione, come i quadri più recenti.
jMock inoltre non ha avuto una versione stabile per oltre 4 anni. jMock 2.6.0 richiesto 2 anni per andare da RC1 a RC2, e poi altri 2 anni prima che effettivamente stato rilasciato.
Per quanto riguarda Proxy & CGLIB vs strumentazione:
(EasyMock e jMock) si basano su java.lang.reflect.Proxy, che richiede un'interfaccia essere implementato. Inoltre, essi sostenere la creazione di oggetti mock per le classi attraverso CGLIB sottoclasse generazione. A causa di ciò, ha detto classi non possono essere definitiva e solo metodi istanza Overridable possono essere deriso. La cosa più importante, tuttavia, quando si utilizzano questi strumenti i dipendenze di codice in prova (che tra gli oggetti di altre classi di che una determinata classe in prova depends) deve essere controllata dal test, in modo che le istanze possono essere finti passò ai clienti di coloro dipendenze. Pertanto, le dipendenze non può semplicemente essere istanziato con il nuovo operatore in una classe client per quale vogliamo unit test di scrittura.
In definitiva, le limitazioni tecniche di strumenti convenzionali beffardi imporre le seguenti restrizioni di progettazione su codice di produzione:
- Ogni classe che possono avere bisogno di essere preso in giro in un test deve o implementare un'interfaccia separata o non essere definitiva.
- Le dipendenze di ogni classe da testare devono essere sia ottenuto attraverso la creazione dell'istanza configurabile metodi (fabbriche o di un servizio Locator), o essere esposti per la dipendenza iniezione. Altrimenti, unit test no poter passare implementazioni fittizie delle dipendenze all'unità sotto prova.
- Poiché solo i metodi istanza possono essere schernivano classi da unità testata non si può chiamare i metodi statici su loro dipendenze, né Instantiate utilizzando uno qualsiasi dei costruttori.
È possibile che questo viene copiato dal http://jmockit.org/about.html . Inoltre, mette a confronto tra se stesso (JMockit), PowerMock, e Mockito in diversi modi:
Ora ci sono altri strumenti per beffardi Java, che superato anche la limiti di quelli convenzionali, tra di loro PowerMock, jEasyTest, e MockInject. Quello che più si avvicina al set di funzionalità di JMockit è PowerMock, così sarò breve valutare qui (inoltre, gli altri due sono più limitato e non sembrano essere attivamente sviluppato più).
JMockit vs PowerMock
- Prima di tutto, PowerMock non fornisce un API completa per beffardo, ma invece funziona come un'estensione un altro strumento, che attualmente possono essere EasyMock o Mockito. Questo è ovviamente un vantaggio per gli utenti esistenti di questi strumenti.
- JMockit, d'altra parte, offre del tutto nuove API, anche se sua API principale (aspettative) è simile sia EasyMock e jMock. Anche se questo crea una curva di apprendimento più lungo, permette inoltre di fornire un JMockit più semplice, più coerente, e più facile per l'uso di API.
- Rispetto alle API aspettative JMockit, l'API è PowerMock più "basso livello", costringendo gli utenti ad capire e specificare quali classi necessità di essere preparati per le prove (con il @PrepareForTest ({ClassA.class,...}) annotazione) e che richiedono chiamate API specifiche per risolvere vari tipi di costrutti del linguaggio che possono essere presenti nella produzione codice: metodi statici (MockStatic (ClassA.class)), costruttori (Sopprimere (costruttore (ClassXyz.class))), invocando un costruttore (ExpectNew (AClass.class)), parziale irride (createPartialMock (ClassX.class, "MethodToMock")), ecc.
- con le aspettative JMockit, tutti i tipi di metodi e costruttori sono deriso in modo puramente dichiarativa, con scherno parziale specificata tramite le espressioni regolari nella @Mocked annotazione o semplicemente "non-beffardo" i membri senza registrata le aspettative; vale a dire, lo sviluppatore semplicemente dichiara alcune condivisa "finto i campi" per la classe di test, o qualche "Campi finti locali" e / o "finto parametri" per singolo test metodi (e in quest'ultimo caso la annotazione @Mocked spesso non sarà necessario).
- Alcune funzionalità disponibili in JMockit, come il supporto per beffardo pari e hashCode, override i metodi e gli altri, non sono al momento supportato in PowerMock. Inoltre, v'è equivalente alla capacità di JMockit a istanze di acquisizione e finto implementazioni di base specificata tipi come viene eseguito il test, senza il codice di prova aventi una stessa la conoscenza della effettiva attuazione classi.
- PowerMock utilizza caricatori di classe personalizzati (di solito uno per classe di prova) al fine di generare versioni modificate delle classi deriso. Tale uso pesante di costume caricatori di classe può portare a conflitti con librerie di terze parti, da qui la necessità di utilizzare talvolta la @PowerMockIgnore ( "package.to.be.ignored") annotazione classi di test.
- Il meccanismo utilizzato da JMockit (strumentazione runtime attraverso un "Agente Java") è più semplice e più sicuro, anche se richiede un passaggio parametro "-javaagent" al JVM quando sviluppare il JDK 1.5; il JDK 1.6 + (Che può sempre essere utilizzato per lo sviluppo, anche se la distribuzione su un versione precedente) non esiste requisito necessario, poiché JMockit lattina in modo trasparente caricare l'agente Java su richiesta utilizzando l'API Attach.
Un altro strumento beffardo recente è Mockito. Anche se non tenta di superare i limiti di anziani strumenti (JMock, EasyMock), lo fa introdurre un nuovo stile di comportamento il test con mock. JMockit anche sostiene questo stile alternativo, attraverso l'API Verifiche.
JMockit vs Mockito
- Mockito si basa su chiamate espliciti le sue API al fine di codice separato tra il record (quando (...)) e verificare (verifica (...)) fasi. Questo mezzi che qualsiasi invocazione di un mock oggetto nel codice di prova richiederà anche una chiamata al API scherno. Inoltre, questo porterà spesso a ripetitivi Quando (...) e verificare (finto) ... chiamate.
- Con JMockit, non esistono chiamate simili. Certo, abbiamo il nuovo NonStrictExpectations () e nuovi Verifiche () chiamate costruttore, ma si verificano solo una volta per test (Tipicamente), e sono completamente separare dalle invocazioni agli metodi deriso e costruttori.
- Il Mockito API contiene diverse incongruenze nella sintassi utilizzata per invocazioni a metodi giro. Nel fase di registrazione, abbiamo chiamate come quando (mock.mockedMethod (args)) ... mentre nella fase di verifica questa stessa chiamata sarà scritto come verificare (finte) .mockedMethod (args). Si noti che nel primo caso la invocazione mockedMethod è fatta direttamente sull'oggetto finto, mentre in secondo caso viene effettuata sulla oggetto restituito da verificare (finto).
- JMockit non ha tali incongruenze perchè invocazioni a Metodi deriso avvengono sempre direttamente sulle istanze deriso loro stessi. (Con una sola eccezione solo: per abbinare invocazioni sullo stesso esempio schernito, un onInstance (finto) chiamata è utilizzato, con conseguente codice come onInstance (finto) .mockedMethod (args); maggior parte dei test non avranno bisogno di utilizzare questo, però.)
- Proprio come altri strumenti beffardi che si basano su metodo concatenamento / involucro, Mockito anche piste in sintassi incoerente se sradicamento Metodi nulli. Ad esempio, si scrive quando (mockedList.get (1)). thenThrow (nuova RuntimeException ()); per un non-vuoto metodo e doThrow (nuova RuntimeException ()) quando (mockedList) .clear ().; per un uno vuoto. Con JMockit, è sempre la stessa sintassi: mockedList.clear (); risultato = new RuntimeException ();.
- Ancora un altro incoerenza si verifica nell'utilizzo delle spie Mockito: "prende in giro" che permettono i metodi reali per essere eseguito nell'istanza spiato. Per esempio, se spia si riferisce ad un vuoto Lista, quindi invece di scrivere quando (spy.get (0)). thenReturn ( "foo") si sarà necessario scrivere doReturn ( "foo"). Quando (spia) .get (0). Con JMockit, la funzione beffardo dinamica fornisce una funzionalità simile a spie, ma senza questo problema dal momento che metodi di reali solo vengono eseguiti durante il la fase di riproduzione.
- In EasyMock e jMock, le API prima beffardo per Java, l'attenzione era interamente sulla registrazione delle atteso invocazioni di metodi prendere gioco oggetti mock che (di default) non lo fanno consentire invocazioni inaspettate. quelli APIS anche fornire la registrazione dei invocazioni consentiti per oggetti mock che permettono invocazioni inaspettati, ma questo è stato trattato come un seconda classe caratteristica. Inoltre, con questi strumenti non v'è alcun modo per esplicitamente verificare invocazioni di mock dopo la codice in prova viene esercitato. tutto come le verifiche sono effettuate in modo implicito e automaticamente.
- In Mockito (e anche in Unitils Mock), il punto di vista opposto è prese. Tutte le invocazioni a oggetti mock che possono accadere durante la prova, sia registrato o meno, sono consentiti, mai aspettato. La verifica è eseguita in modo esplicito dopo il codice in prova si esercita, non automaticamente.
- Entrambi gli approcci sono troppo estreme, e di conseguenza meno che ottimale. JMockit Aspettative e Verifiche è l'unico API che consente la sviluppatore di scegliere senza problemi la migliore combinazione di rigorosa (previsto per impostazione predefinita) e non rigoroso (consentito dalla predefinito) invocazioni finte per ogni prova.
- Per essere più chiari, l'API Mockito ha la seguente lacuna. Se tu necessario verificare che una chiamata a un non vuoto metodo preso in giro è accaduto durante il test, ma il test richiede valore restituito da tale metodo che è diversa da quella di default per il tipo di ritorno, allora il test Mockito avrà il codice duplicato: un quando (mock.someMethod ()). thenReturn (xyz) chiamare in fase di record e un verificare (finto) .someMethod () nella fase di verifica. Con JMockit, un rigoroso aspettativa può sempre essere registrata, che non dovranno essere esplicitamente verificato. In alternativa, l'invocazione Numero di vincolo (volte = 1) possono essere specificata per eventuali registrati non rigorosa aspettativa (con Mockito tale vincoli possono essere specificati solo in un verificare (finto, vincolo) chiamata).
- Mockito ha sintassi povera per le verifiche in ordine, e per la piena verifiche (cioè, controllo che tutte le invocazioni a oggetti fittizi sono esplicitamente verificato). Nel primo caso, un oggetto in più ha bisogno di essere creati, e invita a verificare effettuate su esso: in ordine simmetrico inOrder = inOrder (mock1, mock2, ...). Nel secondo caso, le chiamate come verifyNoMoreInteractions (finto) o verifyZeroInteractions (mock1, mock2) devono essere fatte.
- Con JMockit, è sufficiente scrivere nuovi VerificationsInOrder () o nuova FullVerifications () al posto di nuovo Verifiche () (o nuova FullVerificationsInOrder () per combinare entrambi i requisiti). Non c'è bisogno di specificare che oggetti mock sono coinvolti. No chiamate API beffardi extra. E come un bonus, chiamando unverifiedInvocations () all'interno di un blocco di verifica ordinata, è possibile eseguireverifiche relativi agli ordini che sono semplicemente impossibili in Mockito.
Infine, il JMockit Test Toolkit ha una portata più ampia e più ambizioso obiettivi di altri toolkit beffardi, in Per fornire un servizio completo e sofisticato test di sviluppo soluzione. Una buona API per scherno, persino senza limitazioni artificiali, non è sufficiente per la creazione produttiva test. Un IDE-agnostico, di facile uso, e ben integrato strumento Code Coverage è anche essenziale, ed è quello che JMockit copertura mira a fornire. Un altro pezzo di test di sviluppo set di strumenti che diventerà più utili come la suite di test cresce in termini di dimensioni è il capacità di test incrementale rieseguire dopo un cambio localizzato alla produzione codice; questo è anche incluso nel Copertura strumento.
(concesso, la fonte può essere di parte, ma ben ...)
direi andare con JMockit . E 'il più facile da usare, flessibili, e opere per quasi tutti i casi, anche quelli difficili e scenari quando non è possibile controllare la classe da testare (o non si può rompere a causa di motivi di compatibilità, ecc.).
Le mie esperienze con JMockit sono stati molto positivi.
Altri suggerimenti
Ho lavorato sia con Mockito che con JMockit e la mia esperienza con loro è:
Mockito:
- mocking implicito (-> migliore usabilità, ma presenta il pericolo di non riuscire a rilevare chiamate di metodi non consentite sui mock)
- verifica esplicita
EasyMock:
- esplicita presa in giro
- verifica implicita
JMockit:
- supporta entrambi
Inoltre, altri vantaggi di JMockit:
- se stai prendendo in giro metodi/costruttori statici ecc. (come estendere una base di codice legacy molto vecchia senza UT), avrai due scelte:1) Mockito/EasyMock con estensione Powermock oppure 2) Jmockit
- rapporto di copertura integrato
Personalmente preferisco JMockit, che ritengo sia più ricco di funzionalità e flessibile, ma richiede una curva di apprendimento un po' più ripida.Di solito esistono diversi modi per ottenere lo stesso effetto beffardo e richiede maggiore attenzione durante la progettazione dei mock.
Io uso jMockit soltanto a causa delle sue librerie di riflessione in Deencapsultation.class.In realtà adoro lo stile di Mockito, ma mi rifiuto di modificare il mio codice e di confondere la mia API solo per poterlo fare con un framework di test limitato.E io sono un fan del test di tutto il mio codice, quindi un framework che non può testare facilmente i metodi privati non è quello che voglio utilizzare.
Sono stato influenzato Questo articolo
Dopo una curva di apprendimento (certamente ampia), jMockit è ora il mio principale framework di test unitario per i mock.
Per un facile test della nostra base di codice legacy (con un sacco di chiamate a metodi statici, ecc), JMockit è stato prezioso. [Senza vergogna per un articolo su il mio blog]
Io personalmente preferisco EasyMock .
La capacità di trasferimento tra Nizza, normale e severi controlli beffardi è una mia caratteristica preferita.