Come è il modo corretto di scrivere TDD per un'API void?

5

Ok, quindi il mio scenario è questo: Ho un componente di terze parti che offre un'API per comunicare con un sistema esterno. Il metodo richiede di comandare al sistema esterno di fare cose, tutte restituite void.

Quindi quello che ho fatto è che ho creato un'interfaccia wrapper e ho preso in giro il sistema esterno. Ma dal momento che non ho una vera logica o controlli nel mio codice che chiami roba sull'API esterna, il codice è solo procedurale. Non posso testare nient'altro che i metodi vengono chiamati.

_systemWrapper.DoStuff(a, b ,c , d);
_systemWrapper.DoStuff2(e, f);
_systemWrapper.DoStuff3(g);

Non riesco a configurare il sistema esterno dai miei test, quindi i test di integrazione sono fuori questione.

Quindi quello che ho fatto per testare questo, è che ho preso in giro il mio "_systemWrapper" e sto solo verificando che i parametri che ho chiamato sul mock contengano i parametri corretti. È un modo comune per risolvere questo particolare problema? Per me sembra essere un po 'esauriente fare un test per assicurarti di avere questo e questa linea di codice presente.

Il problema è che questo sistema sta diventando GRANDE e test di scrittura che asseriscono che questa e questa linea è presente sta sfuggendo di mano, e il refactoring sta diventando molto difficile con tutti i test che falliscono se cambiamo una chiamata alla terza parte .

    
posta hkon 17.08.2014 - 22:49
fonte

1 risposta

8

Esistono numerose tecniche per affrontare il problema dell'apis esterno. Proverò a descrivere diversi possibili approcci che potrebbero essere utili.

Mocking

Questo è il punto in cui i test affermano che è stata eseguita una particolare sequenza di chiamate. Questa è la tecnica che hai provato e hai scoperto dove cade. Funziona molto bene quando l'api esterna è molto semplice. Tuttavia, per l'apis complesso, in genere diventa problematico. I test sono fragili e non fanno nemmeno un buon lavoro nel cogliere problemi reali.

Puoi aiutare un po 'la friabilità di questi test, rilassando i test. In genere non è necessario affermare l'esatta sequenza di chiamate di funzione prodotte da un test. Forse i tuoi test possono consentire un maggior numero di passaggi.

Implementazione effettiva

La soluzione ideale, in molti casi, è quella di testare effettivamente l'implementazione reale dell'api. In questo modo puoi affermare che ciò che vuoi succedere effettivamente sta accadendo e non preoccuparti dei parametri esatti che hai passato all'API. Come si nota, "Non riesco a configurare il sistema esterno dai miei test, quindi i test di integrazione sono fuori questione." Quindi sembra che potrebbe non funzionare per te.

Ma a seconda del motivo per cui non è possibile configurare esattamente il sistema esterno in un test, potrebbe comunque esserci un modo per usarlo. Una possibilità è quella di configurare i test in modo che possano essere eseguiti in due modalità. Nella prima modalità, corrono effettivamente contro il sistema esterno e verificano che ciò accada. Tuttavia, registrano anche la sequenza di chiamate api che sono state fatte. Nel secondo, verificate semplicemente che sia stata effettuata la stessa sequenza di chiamate.

Durante lo sviluppo normale, è sufficiente eseguire i test nella seconda modalità, presupponendo che di solito non sia necessario modificare le chiamate effettuate. Ma nel caso in cui si effettua il refactoring del codice e si cambiano le chiamate, si eseguono nuovamente i test contro l'api esterna e si riprende la sequenza di chiamate effettuate. Quindi puoi continuare a programmare facendo in modo che i tuoi test mantengano la nuova sequenza.

Registrazione della sequenza

Un'altra possibilità, è di avere di nuovo due modalità. In modalità di registrazione, si registra la sequenza di chiamate effettuate alla api esterna. Nella modalità di verifica, si verifica che si stanno ancora effettuando le stesse chiamate. Normalmente, si utilizza la modalità di verifica. Tuttavia, ogni volta che è necessario modificare la sequenza di chiamate, si rieseguono i test in modalità di registrazione per acquisire la nuova sequenza di chiamate. Puoi quindi controllare le differenze tra la vecchia e la nuova sequenza per verificare che la sequenza abbia ancora senso.

Usa un falso

Invece di una finta, puoi implementare un falso. La differenza è che il falso agisce come l'api esterna. Modella la api esterna, mantiene uno stato interno simile e / o produce gli stessi risultati. Invece di verificare che siano state fatte le giuste chiamate, verifica che il falso sia stato messo nello stato giusto o abbia fornito lo stesso risultato. Può verificare qualsiasi numero di regole su ciò che i chiamanti dell'api possono fare. Ad esempio, se non puoi chiamare il metodo "foobar" prima di chiamare il metodo "baz", allora il falso può lanciare un'eccezione.

I falsi sono molto simpatici e flessibili, ma richiedono tempo per essere implementati. A volte potresti essere in grado di improvvisare un falso costruendo su librerie / soluzioni esistenti. Ad esempio, un database SQL "reale" può essere simulato utilizzando un database incorporato, come H2 .

Evita l'Api

Puoi provare a strutturare il tuo programma in modo che il meno possibile abbia effettivamente a che fare con l'api esterna. Questo potrebbe richiedere un pensiero intelligente. In genere, è possibile ridurre la quantità di programma che interagisce direttamente con l'API problematica in una piccola parte.

    
risposta data 18.08.2014 - 00:58
fonte

Leggi altre domande sui tag