Si dovrebbero prendere in giro altre istanze di SUT?

1

Considera un campo di gioco, con vari tipi di giocatori (diciamo Hunter s e Animal s), tutti in movimento sul campo di gioco (e facendo alcune altre cose). Ad esempio, in un test unitario per la classe Hunter , possono esserci casi di test, poiché Hunter collide con Animal e Hunter collide con un altro Hunter . Quest'ultimo potrebbe assomigliare a questo.

public class TestHunter {

    private Hunter hunter; // SUT

    @Mock // <-- should we?
    private Hunter hunter2;

    // initialization code, not important...

    @Test
    public void testCollideWithHunter() {
        hunter.collideWithHunter(hunter2);
        assert(/* something with hunter, not important */);
    }

}

Domanda: in questo caso hunter2 (che non è l'obiettivo dei test), essere deriso o no?

La mia conclusione è che in questo caso hunter2 è solo un'altra dipendenza (sebbene, sembra essere della stessa classe del Sistema sotto test), quindi dovrebbe essere deriso. Pertanto sarei interessato soprattutto ad ascoltare le controspermie, ovvero perché hunter2 dovrebbe non essere deriso?

    
posta Attilio 09.08.2016 - 15:30
fonte

2 risposte

3

why hunter2 should not be mocked?

Normalmente non prendevo in giro un'altra classe, a meno che non avessi una necessità pressante. Se non prendi in giro quanto sopra, il tuo test eserciterà la tua vera classe e il tuo codice reale, nell'istanza di questo test.

Normalmente è una buona cosa, vorrei suggerire.

Considerato quanto sopra, dove dovrei usare il mocking?

  1. se quella classe era sufficientemente complessa da poter creare problemi intorno al test se / quando fallisce
  2. (ancora più importante) se non riesco a istanziare quella classe dipendente in un modo adatto per il test. per esempio. rappresenta un sistema remoto (un database) o un accesso di questo tipo? Ci vuole molto tempo o molte dipendenze per istanziare o eseguire il test?

In breve, opterei per la classe reale laddove possibile. Fai finta di niente, quando hai difficoltà a usare la classe originale.

    
risposta data 09.08.2016 - 16:13
fonte
2

Come spesso - dipende .

Il derisione non è un fine in sé, i suoi obiettivi sono rendere i test automatici più semplici, più veloci e dovrebbero aiutare a testare le cose in un isolamento migliore. Se la creazione di un secondo oggetto "Hunter" non è significativamente più complicata della creazione di un oggetto fittizio (ad esempio, se un oggetto "Hunter" può essere facilmente creato con pochi parametri nella memoria principale, senza la necessità di estrarlo da un database o altra risorsa esterna), quindi l'utilizzo di una simulazione può rendere le cose inutili e complicate e diventa inutile.

Dovresti anche considerare in che modo collideWithHunter è implementato internamente. Quando chiama un gruppo di altri metodi complessi del secondo oggetto Hunter , per il quale sono già stati scritti test di unità individuali, è logico prendere in giro questi metodi. In questa situazione, puoi solo convalidare il metodo collideWithHunter in isolamento, e non quegli altri metodi. Se, tuttavia, collideWithHunter utilizza solo getter e setter del secondo oggetto, l'uso di una simulazione non ti aiuterà a cogliere la causa principale di eventuali regressioni più rapidamente o più facilmente.

Nota che tutto ciò che ho scritto sopra è vero anche quando hai due oggetti di diverse classi, questo non è affatto speciale per la situazione in cui hai due oggetti della stessa classe.

    
risposta data 09.08.2016 - 15:51
fonte

Leggi altre domande sui tag