Affinché qualcosa possa essere chiamato mockable , devi essere in grado di sostituire la sua implementazione con un'altra implementazione nel contesto di un test unitario, senza influenzare il codice utilizzato durante il normale runtime. Questo è usato per rendere più facile il test, non tirando fuori una tonnellata di dipendenze o eseguendo operazioni che richiedono molte risorse.
Ci sono una serie di errori in quell'articolo. Prima di tutto, quando usi un tratto, dovresti pensarlo come copia e incolla del codice del tratto nella tua classe. Il codice del tratto diventa parte della classe e quindi parte dell'unità che stai testando. Il fatto che i tratti non siano ingannevoli è un po 'ridicolo. È come lamentarsi del fatto che le classi base non siano irrisolvibili.
Se un tratto non ha senso come parte dell'unità, non dovrebbe essere un tratto. Dovresti usare un altro mezzo per condividere la funzionalità, come ereditarietà o composizione. Come ogni altra caratteristica del linguaggio, ci sono situazioni buone e cattive in cui usare i tratti.
In secondo luogo, i tratti sono mockable, sebbene non altrettanto facilmente. In genere dovresti evitarlo, proprio come generalmente eviterai di deridere qualsiasi altro metodo della classe che stai testando. Ad esempio:
trait MyTrait {
public function traitFunction() {
expensiveDatabaseCall();
}
}
class MyClass {
use MyTrait;
}
Per simulare il tratto, usa qualcosa come il seguente nel tuo test unitario:
trait MockTrait {
public function traitFunction() {
echo "don't have to make a database call";
}
}
class TestMyClass extends MyClass {
use MockTrait;
}
Questa è una variante della tecnica "sottoclasse e override" di Michael Feathers nel suo libro Funzionante in modo efficace con il codice legacy .
Ancora una volta, la tecnica non è la prima scelta per i test unitari, ma lo farà in un colpo solo. La preferenza sarebbe quella di simulare expensiveDatabaseCall()
.
Gli oggetti fittizi vengono solitamente passati come argomento a un costruttore o un metodo. Non puoi passare un tratto come argomento, che sospetto sia il motivo per cui l'autore di quell'articolo li ha definiti non raggianti, ma è lontano dal fatto che i tratti ti impediscano di testare efficacemente una classe con una unità, anche se non ti prendi in giro loro.
In effetti, l'utilizzo corretto dei tratti può semplificare il codice, rendendolo più facile al test unitario. Riducono il boilerplate e riducono il codice "plumbing" che esiste solo per connettere altre classi che fanno il vero lavoro.