Di recente ho letto un articolo in cui si diceva che gli oggetti finti sono spesso fraintesi e abusati. Ci sono dei chiari anti-schemi beffardi che posso cercare?
Di recente ho letto un articolo in cui si diceva che gli oggetti finti sono spesso fraintesi e abusati. Ci sono dei chiari anti-schemi beffardi che posso cercare?
Risposte:
Odio vedere derise semplici classi concrete. Ad esempio, prendi la seguente semplice classe che non ha dipendenze da nient'altro:
public class Person
{
private readonly string _firstName;
private readonly string _surname;
public Person(string firstName, string surname)
{
if (String.IsNullOrEmpty(firstName))
{
throw new ArgumentException("Must have first name");
}
if (String.IsNullOrEmpty(surname))
{
throw new ArgumentException("Must have a surname");
}
_firstName = firstName;
_surname = surname;
}
public string Name
{
get
{
return _firstName + " " + _surname;
}
}
}
In tutti i test che coinvolgono questa classe, preferirei che ne venisse istanziata e usata una vera e propria piuttosto che estrarre un'interfaccia come "IPerson", una beffa usata e aspettative impostate. Usando quello reale il test è più realistico (hai i controlli dei parametri in atto e l'implementazione reale della proprietà 'Nome'). Per una classe semplice come questa non stai rendendo i tuoi test più lenti, meno deterministici o confondendo la logica (non è probabile che tu abbia bisogno di sapere che il nome è stato chiamato durante il test di un'altra classe) - che sono le solite ragioni per deridere / sradicamento.
Come estensione di questo ho anche visto persone scrivere test in cui il mock è impostato con un'aspettativa, quindi il mock viene chiamato direttamente nel test. Senza sorprese il test passerà sempre ... hmmmm ...
Potrebbe sembrare ovvio, ma: non usare oggetti finti nel codice di produzione! Ho visto più di un esempio in cui il codice di produzione dipendeva dalle caratteristiche di alcuni oggetti finti ( MockHttpServletRequest
ad esempio da Springframework).
Secondo me è l'eccessivo controllo dell'invocazione del metodo su beffe. Sento che questa è una pratica applicata da alcuni framework di derisione come EasyMock, in cui il comportamento di simulazione predefinito fallisce ogni volta che viene invocata una metodologia aggiuntiva che ciò che non era stato specificato in precedenza. Questo tipo di rigoroso controllo del metodo simulato può portare a progetti fragili in cui la più piccola modifica al codice può portare a un'intera serie di test che falliscono, anche se la funzionalità di base è sempre la stessa.
Una soluzione a questo sta iniziando a usare gli stub invece dei mock. Un articolo che ho trovato particolarmente illuminante sull'argomento è stato trovato in Javadoc di Mockito: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (vedi "2. Che ne dici di un po 'di stub?" ), che collega a: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .
Finora mi sono divertito a lavorare con Mockito perché non impone questo rigoroso comportamento beffardo ma l'uso di stub. Applica inoltre il controllo del metodo su quelli specifici invece dell'intero oggetto simulato; quindi finisci per controllare solo i metodi che contano davvero nel tuo scenario di test.
Ci sono alcuni libri qua e là che posso consigliare di toccare questo argomento, beffardo e generale:
xUnit Patterns
L'arte del test unitario: con esempi in .Net
Test Java di prossima generazione: TestNG e Advanced Concepts (questo libro tratta principalmente di testNG ma c'è un bel capitolo sul deridere)
Answer.RETURNS_SMART_NULLS
impostazione per le beffe che aiuta a diagnosticare questo.
Ho osservato alcuni anti-schemi nella mia esperienza.
Altrimenti la mia esperienza con le beffe in particolare Mockito è stata un gioco da ragazzi. Hanno reso i test molto facili da scrivere e gestire. Il test di interazione con GWT view / presenter è molto più semplice con simulazioni rispetto a GWTTestCase.
Trovo che i test che utilizzano simulazioni su più livelli di un'applicazione siano particolarmente difficili da decifrare e modificare. Tuttavia, penso che questo sia stato mitigato negli ultimi anni da API mock framework migliorate (uso JMock dove conveniente).
5 o 6 anni fa le API come EasyMock erano potenti ma molto ingombranti. Spesso il codice di test che lo utilizzava era ordini di grandezza più complicati del codice che stava testando. Allora ho cercato di influenzare i team in cui ero in uso con parsimonia e accontentarmi di semplici derisioni artigianali che erano semplicemente implementazioni alternative di interfacce specifiche per i test.
Recentemente le mie forti opinioni su questo argomento sono diventate più morbide poiché le API beffe hanno reso i test che li utilizzano più leggibili. In sostanza, voglio che il mio codice (compresi i test) sia modificabile da altri sviluppatori senza farli sentire come se stessero setacciando attraverso un mucchio di oscure chiamate API.