Questo è un modo problematico di scrivere test perché il test non specifica l'istanziazione del SUT. Il Fixture e implicitamente con esso il SUT saranno istanziati dal framework di test. Questo porta ai seguenti problemi:
- Non puoi fornire argomenti del costruttore.
- A seguito di ciò, non è possibile impostare grafici di oggetti complicati o eseguire un'iniezione di dipendenza manuale.
- Questo porta a problemi se l'istanza SUT deve essere creata solo attraverso una fabbrica, o se deve essere registrata da qualche parte nell'applicazione per funzionare correttamente.
- Lo stesso oggetto viene riutilizzato per tutti i casi di test (forse - dipende dal framework di testing).
- Non puoi ripristinare lo stato SUT per il prossimo test a meno che non sia mutabile.
Per evitare tali problemi, ti consiglio di impostare SUT all'interno di ogni caso di test e di fare affidamento solo su dispositivi automatici se semplificano notevolmente i test.
Come già accennato, l'uso dell'ereditarietà stessa potrebbe essere problematico.
- Il fragile problema della classe base: le modifiche benigne alla classe base potrebbero interrompere le classi derivate. C # rende questo difficile da fare, ma non è impossibile. In tutte le lingue: una classe deve essere progettata esplicitamente per ereditarietà se deve essere utilizzata come classe base.
- Le aggiunte nella classe derivata potrebbero modificare accidentalmente il comportamento dell'oggetto. Ancora una volta, C # rende questo difficile ma non impossibile. Se il tuo servizio è soggetto a riflessione o può implementare interfacce opzionali, aggiunte come il fatto che il tuo dispositivo erediti da IDisposable potrebbero avere conseguenze indesiderate.
Ci sono casi in cui l'ereditarietà potrebbe essere la soluzione corretta: quando il SUT è previsto come una classe base e i test devono accedere ai membri protetti. Altrimenti, è meglio mantenere una certa distanza tra il codice di produzione e i test.
Inoltre, questo è un modo non ovvio e inutilmente intelligente per scrivere test. Le sorprese sono cattive. Come discusso in Come sapresti se hai scritto un codice leggibile e facilmente gestibile? , ci sono un paio di indicatori questo approccio è buono o cattivo. Un estratto:
-
Your peer tells you after reviewing the code.
Hai detto al tuo collega che questo potrebbe non essere l'ideale, il che è un buon indicatore che non lo è.
-
It is:
- maintainable if you can maintain it.
-
easily maintainable if someone else can maintain it without asking you for help
- readable if someone else, on reading it, correctly understands the design, layout and intent
Non capisco perché il test abbia sia scritto in questo modo non ortodosso. Sicuramente c'era una ragione speciale per questo? Dovrei chiedere.
-
Watch what happens after handing it off to a reasonably competent person. If they don't need to ask many questions relative to the difficulty of the code, you've done a good job.
Questo è un codice molto semplice, ma solleva delle domande.
Se si lascia questo codice non necessario nella base di codice, si sta anche impostando un cattivo esempio. Di per sé, questa eredità non è veramente dannosa. Ma in altri casi, i suddetti inconvenienti potrebbero influire sulla validità dei test.