Come menzionato dalla risposta più votata, Martin Fowler discute queste distinzioni in Mocks Aren't Stubs , e in particolare nel sottotitolo The Difference Between Mock and Stubs , quindi assicurati di leggere l'articolo.
Invece di concentrarmi sul modo in cui queste cose sono diverse, penso che sia più illuminante concentrarsi sul perché questi sono concetti distinti. Ognuno esiste per uno scopo diverso.
falsi
Un falso è un'implementazione che si comporta "naturalmente", ma non è "reale". Questi sono concetti confusi e quindi persone diverse hanno una comprensione diversa di ciò che rende le cose un falso.
Un esempio di falso è un database in memoria (ad es. Usando sqlite con l' :memory:
archivio). Non lo useresti mai per la produzione (poiché i dati non sono persistenti), ma è perfettamente adeguato come database da utilizzare in un ambiente di test. È anche molto più leggero di un database "reale".
Come altro esempio, forse usi un qualche tipo di archivio oggetti (es. Amazon S3) in produzione, ma in un test puoi semplicemente salvare oggetti su file su disco; quindi l'implementazione "salva su disco" sarebbe un falso. (O potresti persino falsificare l'operazione "salva su disco" utilizzando invece un filesystem in memoria.)
Come terzo esempio, immagina un oggetto che fornisce un'API cache; un oggetto che implementa l'interfaccia corretta ma che semplicemente non esegue affatto la memorizzazione nella cache ma restituisce sempre un errore nella cache sarebbe una specie di falso.
Lo scopo di un falso non è influenzare il comportamento del sistema in prova , ma piuttosto semplificare l'implementazione del test (rimuovendo dipendenze non necessarie o pesanti).
stubs
Uno stub è un'implementazione che si comporta "in modo innaturale". È preconfigurato (solitamente dall'impostazione del test) per rispondere a ingressi specifici con uscite specifiche.
Lo scopo di uno stub è di mettere il sistema sotto test in uno stato specifico. Ad esempio, se si sta scrivendo un test per un codice che interagisce con un'API REST, è possibile stub l'API REST con un'API che restituisce sempre una risposta predefinita o che risponde a una richiesta API con un errore specifico. In questo modo è possibile scrivere test che fanno affermazioni su come il sistema reagisce a questi stati; ad esempio, testando la risposta che ottengono gli utenti se l'API restituisce un errore 404.
Uno stub di solito è implementato per rispondere solo alle interazioni esatte a cui gli hai detto di rispondere. Ma la caratteristica chiave che rende qualcosa uno stub è il suo scopo : uno stub è tutto sulla configurazione del test case.
Mocks
Un mock è simile a un troncone, ma con la verifica aggiunta. Lo scopo di un mock è fare affermazioni su come il sistema in test ha interagito con la dipendenza .
Ad esempio, se si sta scrivendo un test per un sistema che carica file su un sito Web, è possibile creare una simulazione che accetta un file e che è possibile utilizzare per affermare che il file caricato era corretto. Oppure, su scala ridotta, è comune utilizzare una simulazione di un oggetto per verificare che il sistema sottoposto a test chiami metodi specifici dell'oggetto deriso.
Le simulazioni sono legate ai test di interazione , che è una metodologia di test specifica. Le persone che preferiscono testare lo stato del sistema piuttosto che le interazioni del sistema useranno con parsimonia se non del tutto.
Il test raddoppia
Falsi, tronconi e beffe appartengono tutti alla categoria dei doppi di test . Un doppio test è qualsiasi oggetto o sistema che usi in un test invece di qualcos'altro. La maggior parte dei test del software automatizzato prevede l'uso di duplicati di test di un tipo o di un altro. Alcuni altri tipi di test raddoppia includono valori fittizi , spie , e di I / O blackholes .