2014-12-22 2 views
19

Ho due oggetti A e B. L'oggetto A è il risultato effettivo che ottengo durante il test di JUnit. L'oggetto B è eseguire una chiamata db di fine effettiva e assumere come previsto la revisione. Devo affermare che due istanze dell'oggetto A e B sono uguali nel valore e non nell'oggetto reale.Test di due istanze di oggetto sono uguali JUnit

Abbiamo un metodo chiamato assertEquals(obj expected, obj actual) in JUnit ma non desidero in questo modo.

C'è un modo o una soluzione per ottenere lo stesso?

risposta

1

puoi affermare ogni membro di questi 2 oggetti!

ad es. assertThat(actual).isEqualToComparingFieldByField(expected);

1

assertEquals() chiamate equals() sui tuoi oggetti e non c'è modo di aggirare questo. Quello che puoi fare è implementare qualcosa come public boolean like(MyClass b) nella tua classe, in cui dovrai confrontare qualsiasi cosa tu voglia. Quindi, è possibile controllare il risultato utilizzando assertTrue(a.like(b)).

+1

Ciò significa inquinare il vostro codice di produzione con un metodo puramente per il test. Anche l'utilizzo di assertTrue non ti darà assolutamente nessuna diagnosi su/perché/il test ha fallito – tddmonkey

+0

Sono d'accordo sul codice di produzione inquinante con il codice di test, ma non sulla diagnostica perché il test ha avuto esito negativo. Se non è riuscito, ha fallito perché gli oggetti reali non sono "come" previsti. Se vuoi informazioni più precise, aggiungi una serie di asserzioni per ogni campo pertinente. –

+0

La diagnostica che ottieni da questo è qualcosa come "expected true: got false". Se si modifica il test per utilizzare meglio le asserzioni, non è necessario eseguire altri lavori.Se vedi la mia risposta, tutti i suggerimenti produrranno una diagnostica di qualità non solo per dire che il test è fallito, ma anche perché – tddmonkey

1

È necessario sostituire il metodo equals e il metodo per la propria classe. Successivamente, assertEquals(obj expected, obj actual) non verificherà la presenza di riferimenti ma utilizzerà la logica implementata nel metodo equals.

+3

Considero questa pessima pratica. Stai prevalendo uguali puramente per soddisfare un test che ha bisogno di confronto campo per campo. Se il contratto equals cambia in seguito, il test passerà comunque, ma non sarà fondamentalmente rotto – tddmonkey

+1

@MrWiggles Se abbiamo 2 istanze di Qualche classe X, allora non è meglio avere un'implementazione decente di 'equal' così ogni volta che è necessario confrontiamo quegli oggetti che possiamo contare sull'implementazione di equals piuttosto che sull'implementazione di default 'equals' ereditata dalla classe Object – sol4me

+1

Se il tuo codice di produzione ha bisogno di uguali allora sì, per esempio se lo stai inserendo in un Set. Il problema con l'override di un controllo di campo come in questa istanza è che si esegue un'implementazione di default uguale a ogni singolo campo. Se in un secondo momento il metodo equals dovrebbe cambiare per un vero motivo aziendale, ad es. confronta solo su ID, il test che inizialmente lo richiedeva è ora rotto ma non fallirà. Inoltre, l'utilizzo di uguali per questo test non ti darà informazioni diagnostiche sul perché gli oggetti sono diversi, solo che sono – tddmonkey

14

Pensa esattamente a cosa stai cercando di raggiungere. Vuoi testare l'identità dell'oggetto o verificare che i due oggetti abbiano esattamente gli stessi dati? Dal tuo suggerimento di assertEquals, suppongo che tu voglia andare field-by-field.

Se gli oggetti sono poco profondi è possibile utilizzare

assertThat(actual, samePropertyValuesAs(expected)); 

Questo non riesce quando l'oggetto è un composito però. Se si vuole camminare l'intero grafico è possibile utilizzare il sameBeanAs matcher abbiamo scritto qualche tempo fa per risolvere questo problema:

assertThat(actual, sameBeanAs(expected)); 

Se stai usando AssertJ allora si può anche utilizzare la funzionalità built-in in questo modo:

assertThat(actual).isEqualToComparingFieldByField(expected); 

una cosa che non si vuole farlo l'override del metodo equals anche per questo che potrebbe cambiare in futuro per soddisfare esigenze aziendali.

+0

Conosci qualche abbinatore di Hamcrest che possiamo usare? – sol4me

+1

samePropertyValuesAs è un rilevatore di Hamcrest incorporato. sameBeanAs è un matcher Hamcrest personalizzato che abbiamo scritto a Shazam per risolvere questo problema esatto – tddmonkey

+0

Usa assertThat (effettivo) .isEqualToComparingFieldByFieldRecursively (previsto) se hai un oggetto all'interno dell'oggetto. – vis