Ho iniziato a fare affidamento su un framework di simulazione in php per i miei test di unità.
La mia preoccupazione è che con un linguaggio dinamico, non c'è modo di imporre un tipo di ritorno. Quando fai il mocking, devi assicurarti che il tipo di ritorno del tuo metodo di simulazione sia corretto.
Prendi ad esempio la seguente interfaccia
interface MyInterface {
/**
* @return SomeObject
*/
public function myMethod();
}
Se stiamo testando un'unità con una classe che richiede un'istanza di MyInterface
, prendiamo in giro la funzione myMethod
per restituire un SomeObject
noto.
La mia preoccupazione è ciò che accade se accidentalmente il nostro metodo di simulazione restituisce un tipo diverso di oggetto, ad es. SomeOtherObject, and SomeOtherObject and SomeObject are not the same duck type (don't have the same methods). We'll now have code that is relying on having
SomeOtherObject , when all implementations of
MyInterface myMethod
will return
SomeObject'.
Ad esempio, potremmo scrivere il seguente codice di produzione;
$someOtherObject = $myInterfaceImp->myMethod();
$newObj = new NewObject($someOtherObject);
Speriamo che il problema sia ovvio. Stiamo passando ciò che pensiamo sia SomeOtherObject
in un costruttore. I nostri test passeranno, ma è molto probabile che in produzione avremo fallimenti come myMethod()
restituirà effettivamente SomeObject
. Proviamo quindi a passare questo nel costruttore e ottenere un errore se è presente un controllo di tipo o viene chiamato un metodo inesistente.
A meno che non scriviamo test di integrazione e accettazione molto dettagliati utilizzando le reali implementazioni (in pratica dovremmo assicurarci che coprano tutti i test che facciamo a livello di unità) potremmo non renderci conto che abbiamo un problema finché non ne riceviamo alcuni errore di runtime in produzione.
Oltre alla disciplina per sviluppatori, esiste un modo per mitigare il rischio di mock e implementazioni non corrette?