Metodi di creazione dell'oggetto previsto per l'asserzione

2

Recentemente, ho iniziato a usare TDD. È davvero interessante e divertente, ma creare oggetti attesi per assertEquals è molto noioso e noioso.

Al momento vedo solo due vie:

Semplice
Creare oggetti nel codice usando milioni di setter. Usando questo approccio una parte maggiore dei test sta creando l'oggetto previsto. Penso che non sia molto bello.

serializzazione
Scrivere l'oggetto previsto per esempio in JSON e quindi serializzarlo in prova. Non riesco a trovare svantaggi in questo modo eccetto la possibilità di uno stato incoerente tra i miei bean e i file di test.

Modifica

toString () ( @Kilian Foth commento )
Qualche tipo di serializzazione, ma penso che meriti attenzione. Definisci un toString () strettamente controllato e asserisci uguaglianza con una stringa letterale piuttosto che con un secondo oggetto.

Configurazione nel contenitore DI ( ispirato a @Spotted )
Mi sono ricordato di DI. Qualcuno configura il bean previsto in DI (Spring XML per esempio) e poi lo inietta per testare il metodo? È un approccio cattivo e poco efficiente o qualcosa di normale?

Esistono altre tecniche / approcci o strumenti speciali che possono accelerare tale processo?

    
posta Vladislav Koroteev 20.10.2015 - 13:09
fonte

2 risposte

2

A meno che non si stia testando in modo specifico il metodo equals() di una classe, di solito non c'è motivo per un test unitario di affermare l'uguaglianza di due oggetti. Un test unitario dovrebbe testare un comportamento e non tutte caratteristiche di un'unità di codice, che si tratti di un modulo, di una classe o anche di un metodo (un metodo con molti possibili input di solito ha bisogno di molti test unitari e non solo uno).

Pertanto, spesso non è necessario creare un simile "oggetto di confronto". Se stai verificando che una transazione metta il cliente nello stato corretto, ottieni il cliente e assert cose sul suo stato, non che sia esattamente uguale a un altro oggetto complesso fornito dal test. Questo è quasi certamente un test troppo complesso in un modo molto fragile, dal momento che qualsiasi modifica alla classe cliente potrebbe interrompere il test di "stato".

    
risposta data 20.10.2015 - 13:21
fonte
0

Un'altra alternativa che vorrei suggerire è la seguente:

Invece di controllare che l'intero oggetto risultato corrisponda al valore previsto, scrivi più asserzioni che controllano le proprietà importanti dell'oggetto.

Ora, alcune persone sostengono che si dovrebbe avere solo 1 assert in un test. Hanno ragione di affermare 1 cosa, ma questo non significa necessariamente che hai solo 1 assert.

Esempio: supponiamo di avere una testcase che verifica che dopo una transazione bancaria, alcuni soldi vengano trasferiti. (Esempio in pseudo-codice):

function testMoneyMovedAfterTransaction():
    account1 = setupFakeAccount(balance=300)
    account2 = setupFakeAccount(balance=600)
    performTransaction(from=account1, to=account2, amount=100)
    assertEquals(account1.balance, 200)
    assertEquals(account2.balance, 700)

Vedi: due affermazioni, ma sto solo affermando una cosa: il denaro ha spostato i conti, come richiesto.

Allo stesso modo, potrei scrivere un test per ciò che accade quando il saldo è troppo basso. Ciò significherebbe che non accade nulla agli equilibri e si ottiene un'eccezione. Ci vorrebbero tre asserzioni, ma stai solo affermando che nulla è cambiato.

Modifica : se parli di "modelli" come nei blob di testo generati: il più semplice potrebbe essere quello di eseguire una ricerca di sottostringa o di un'espressione regolare contro il testo generato. Per i "modelli" come nelle strutture dati generate: un asserimento per i singoli campi potrebbe essere il più efficace.

    
risposta data 20.10.2015 - 19:22
fonte

Leggi altre domande sui tag