Come posso evitare il codice duplicato nei miei test ed evitare di prendermi in giro da solo?

StackOverflow https://stackoverflow.com/questions/223878

Domanda

Nella mia domanda Come praticante TDD" beffardo ", dovrei prendere in giro altri metodi della stessa classe del metodo in esame? , Avdi ha risposto " Personalmente penso che deridere se stessi sia quasi sempre un odore di codice. Sta testando l'implementazione piuttosto che il comportamento. & Quot; Potrebbe avere ragione, ma spesso non riesco a distinguere tra implementazione e comportamento.

Ho un altro esempio (in pseudo-codice in stile Python) che può portare a risposte utili:

class Consumer:

    def spec_dirpath:
        client = VCS.get_connection(self.vcs_client_name)
        client.sync()
        return client.dirpath()

    def spec_filepath:
        filepath = os.path.join(spec_dirpath(), self.spec_filename)
        if not os.path.exists(filepath):
            raise ConsumerException
        return filepath

    def get_components:
        return Components.get_components_from_spec_file(self.spec_filepath())

L'idea qui è che il metodo get_components chiama il metodo spec_filepath per ottenere un percorso a un file da cui il metodo della classe Components get_components_from_spec_file leggerà un elenco di componenti. Il metodo spec_filepath a sua volta chiama spec_dirpath, che sincronizza la directory contenente il file spec dal sistema VCS e restituisce il percorso a quella directory. (Cerca di non cercare bug in questo codice - dopo tutto è pseudo-codice.)

Sto cercando consigli su come testare questi metodi ...

Il test spec_dirpath dovrebbe essere abbastanza semplice. Posso deridere la classe VCS e farlo restituire un oggetto simulato e confermare che vengono chiamati i metodi appropriati (e che il metodo spec_dirpath restituisce ciò che restituisce il metodo dirpath del mock).

Ma se non derido spec_dirpath mentre collaudo spec_filepath, come posso evitare di duplicare lo stesso codice test dal codice spec_dirpath nel test spec_filepath? E se non derido spec_filepath mentre collaudo get_components, come posso evitare di duplicare il codice di test sia da spec_filepath che spec_dirpath?

È stato utile?

Soluzione

Il test unitario funziona meglio con una qualche forma di iniezione di dipendenza. In questo caso, poiché si sta creando il client nel codice, si crea una dipendenza nel test che richiede una forma di simulazione dinamica per far fronte. (In questo caso useremmo una derisione parziale per deridere le nostre chiamate che creano dipendenze per evitare di dover testare anche quelle dipendenze).

Se si inietta la dipendenza all'avvio (ad esempio Passa in un oggetto client), è possibile prenderlo in giro facilmente e non avere grosse difficoltà a testare solo una classe.

Quindi hai bisogno di una simulazione parziale o di una iniezione di dipendenza per raggiungere quegli obiettivi.

Altri suggerimenti

Di solito nei test unitari, il comportamento si riferisce a comportamenti osservabili esternamente.

Usando il tuo esempio, il comportamento osservabile sarebbe l'elenco dei componenti che ottieni da get. Il fatto che provengano da un file è un'implementazione, quindi ti consiglio di costruire i tuoi test attorno all'elenco dei componenti che ottieni senza deridere il recupero dei file in quanto è interno alla classe, con codice di installazione per fornire un file appropriato.

L'alternativa sarebbe quella di creare il file in cui i componenti sono stati caricati da una dipendenza per la classe, ad es. rendilo un parametro costruttore o parametro metodo, per consentire al file di essere specificato esternamente alla classe. In questo caso sarebbe esterno e quindi lo deriderei per assicurarti che tu abbia un comportamento coerente da esso per assicurarti che la tua classe lo stesse usando correttamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top