Domanda

È meglio aggiungere funzioni che restituiscano lo stato interno di un oggetto per i test unitari, invece di rendere amica la classe testing?- soprattutto quando le funzioni non vengono utilizzate se non nel caso dei test unitari.

È stato utile?

Soluzione

I test unitari dovrebbero il 95% del tempo di testare solo la superficie esposta al pubblico di una classe. Se stai testando qualcosa sotto le coperte, che sta testando i dettagli di implementazione, che è intrinsecamente fragile, perché si dovrebbe essere in grado di cambiare facilmente implementazione e avere ancora il lavoro test. Non solo è fragile, ma si potrebbe anche essere tentato in cose di test che non sono effettivamente possibili in scenari di utilizzo previste, che è una perdita di tempo.

Se il punto delle funzioni di accesso che si desidera aggiungere è solo quello di verificare se la funzione ha avuto l'effetto desiderato, il vostro disegno di classe possa violare un altro principio, che è che una classe di stato macchina-come dovrebbe sempre mettere in chiaro quale stato la sua in se che colpisce ciò che accade quando le persone interagiscono con la classe. In tal caso, sarebbe diritto di fornire quelle funzioni di accesso di sola lettura. Se non influenza il comportamento della classe, fare riferimento al mio precedente bit sui dettagli di implementazione.

E come lei ha giustamente detto, ingombrano la superficie pubblica di una classe con roba inutilizzata è anche auspicabile per le proprie ragioni.

Se I had per scegliere tra di accesso e friending nel tuo caso, avrei scelto friending, semplicemente perché si possedere il test e possono cambiare in un pizzico. E 'vietato il codice proprietario dal clown che trova il modo di utilizzare le funzioni di accesso in più, e poi ti verrà bloccato.

Altri suggerimenti

Non sono d'accordo con la risposta accettata e consiglierò invece l'uso di una classe di amici.

Parte dello stato che stai testando è probabilmente specifico per l'implementazione della tua classe;stai testando dettagli che altri codici normalmente non conoscono o di cui non si preoccupano e su cui non dovrebbero fare affidamento.Le funzioni di accesso pubbliche rendono questi dettagli di implementazione parte dell'interfaccia della classe.Se lo stato interno che stai testando non fa parte dell'interfaccia prevista, non dovrebbe essere visibile tramite le funzioni pubbliche.Da un punto di vista purista sei bloccato tra due risposte sbagliate, poiché anche le classi degli amici fanno tecnicamente parte dell'interfaccia pubblica.Nella mia mente la domanda diventa: quale opzione ha meno probabilità di portare a scelte di codifica inadeguate in futuro?L'utilizzo di un insieme di funzioni di accesso pubbliche dipendenti dall'implementazione incoraggerà inavvertitamente un modello concettuale della classe dipendente dall'implementazione, portando a un uso della classe dipendente dall'implementazione.Una classe con un solo amico, opportunamente denominata e documentata, ha meno probabilità di subire abusi.

Sebbene in generale siano fortemente d'accordo con la raccomandazione di preferire le funzioni di accesso rispetto all'accesso diretto alle variabili membro, non sono d'accordo sul fatto che questa best practice si applichi ai test unitari dello stato interno dipendente dall'implementazione.Una ragionevole via di mezzo è quella da usare privato funzioni di accesso a quelle parti di stato a cui interesserà il tuo test unitario e sii sufficientemente disciplinato da utilizzare le funzioni di accesso nei tuoi test unitari.Solo la mia opinione.

Utilizzo delle classi amico per unit testing è perfettamente legittimo e consente di mantenere l'incapsulamento. Non si dovrebbe modificare la vostra interfaccia pubblica classi semplicemente per rendere la classe più verificabili. Pensare in questo modo. Che cosa succede se si è acquistato un terzo libreria FTP e si sta tentando di usarlo e la sua interfaccia pubblica è ingombra con un sacco di metodi che non hanno nemmeno bisogno di sapere su semplicemente a causa di test di unità! Anche modificando un'interfaccia protetta per compensare unit test è BAD. Se sto eredita da qualche classe, io non voglio avere a preoccuparsi di quali metodi sono utili per me e quali sono lì solo a causa di test di unità !!! Utilizzo delle classi amici per i test unitari aiuta a mantenere un semplice, facile da usare l'interfaccia di classe; aiuta a preservare l'incapsulamento e astrazione !!!

Ho sentito l'argomento che utilizzando le classi amico per unit testing è un male perché la classe in prova non deve essere "strettamente accoppiato" con la sua classe di test e non deve "sapere" nulla circa la sua classe di test. Io non comprare questo. Si tratta di una singola linea aggiunto alla parte superiore della classe:

amico classe MyClassTest;

e ora è possibile verificare la classe in qualsiasi modo che vuoi!

Ora io sono d'accordo che non si deve usare una classe amico meno che non sia necessario. Se è possibile verificare che cosa ha bisogno di prova, senza farne un amico, con tutti i mezzi fanno. Ma se la vita diventa difficile e utilizzando una classe amico rende la vita facile di nuovo, usarlo!

Mi consiglia di utilizzare funzioni di accesso piuttosto che permettere l'accesso tramite membri pubblici o classi amico.

Non credo che l'utilizzo di amico di classe in realtà si ottiene alcun beneficio, e ha il potenziale per rendere la vita molto peggio lungo la strada. Se il codice sta per rimanere in giro per molto tempo c'è una buona probabilità che possa essere utilizzato in modi che non anticipare. Le funzioni di accesso potrebbero essere utilizzate solo per i test ora, ma chissà cosa accadrà in futuro? Utilizzando funzioni di accesso piuttosto che fornire un accesso diretto alle variabili ti dà molta più flessibilità, e ha un costo molto basso.

L'altro argomento è che l'utilizzo di accesso, piuttosto che membri pubblici è una buona abitudine. Lo sviluppo di buone abitudini è un'abilità importante come programmatore.

Come di fare stato interno "protetti"? E poi fare unittest utilizzando classe derivata.

Credo che ci deve essere una distinzione tra a prova di futuro della classe, fornendo funzioni di accesso ai propri utenti se ha senso farlo, e migliorare la verificabilità. Io non sono un grande fan di amicizia con le classi per il solo scopo di test come questo introduce un accoppiamento stretto in un posto dove preferisco non farlo.

Se il solo uso delle funzioni di accesso è quello di fornire un modo per i casi di test per verificare lo stato interno della classe, che normalmente non ha senso di esporli pubblicamente. E 'anche possibile vincolare i dettagli di implementazione che si potrebbe desiderare di cambiare in seguito, ma poi non si può trovare, perché qualcun altro stia utilizzando detto di accesso.

La mia soluzione preferita per questo sarebbe quello di fornire protette funzioni di accesso per comunicare in modo chiaro agli utenti della classe che questi non sono parte dell'interfaccia pubblica. I test sarebbero quindi creare una classe derivata minima dell'originale che contiene stub chiamata-through per le funzioni dei genitori, ma rende le funzioni di accesso del pubblico anche in modo da poter farne uso nei casi di test.

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