Ich habe kürzlich einen Artikel gelesen, in dem es heißt, dass Scheinobjekte oft missverstanden und missbraucht werden. Gibt es eindeutige spöttische Anti-Muster, auf die ich achten kann?
Ich habe kürzlich einen Artikel gelesen, in dem es heißt, dass Scheinobjekte oft missverstanden und missbraucht werden. Gibt es eindeutige spöttische Anti-Muster, auf die ich achten kann?
Antworten:
Ich hasse es, wenn einfache konkrete Klassen verspottet werden. Nehmen Sie zum Beispiel die folgende einfache Klasse, die von nichts anderem abhängig ist:
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;
}
}
}
Bei allen Tests, an denen diese Klasse beteiligt war, wäre es mir lieber, wenn eine echte instanziiert und verwendet würde, als dass eine Schnittstelle wie 'IPerson' herausgezogen, eine verspottete verwendet und Erwartungen an die. Wenn Sie den Real verwenden, ist Ihr Test realistischer (Sie haben die Parameterprüfungen und die reale Implementierung der 'Name'-Eigenschaft eingerichtet). Für eine einfache Klasse wie diese machen Sie Ihre Tests nicht langsamer, weniger deterministisch oder verwirren die Logik (Sie müssen wahrscheinlich nicht wissen, dass der Name beim Testen einer anderen Klasse aufgerufen wurde) - das sind die üblichen Gründe für das Verspotten / Stubbing.
Als Erweiterung dazu habe ich auch Leute gesehen, die Tests geschrieben haben, bei denen das Mock mit einer Erwartung eingerichtet wurde, dann wird das Mock direkt im Test aufgerufen. Es überrascht nicht, dass der Test immer bestanden wird ... hmmmm ...
Es mag offensichtlich klingen, aber: Verwenden Sie keine Scheinobjekte im Produktionscode! Ich habe mehr als ein Beispiel gesehen, in dem der Produktionscode von den Eigenschaften bestimmter Scheinobjekte abhing ( MockHttpServletRequest
z. B. vom Springframework).
Meiner Meinung nach ist es die übermäßige Methodenaufrufprüfung für Mocks. Ich bin der Meinung, dass dies eine Praxis ist, die von einigen Spott-Frameworks wie EasyMock erzwungen wird, bei denen das Standard-Spott-Verhalten immer dann fehlschlägt, wenn ein zusätzlicher Methodenaufruf erfolgt, der zuvor nicht genau angegeben wurde. Diese Art der strengen Überprüfung von Scheinmethoden kann zu spröden Designs führen, bei denen die kleinste Änderung des Codes dazu führen kann, dass eine ganze Reihe von Tests fehlschlägt, obwohl die Kernfunktionalität immer noch dieselbe ist.
Eine Lösung für dieses Problem ist die Verwendung von Stichleitungen anstelle von Schein. Ein Artikel, den ich zu diesem Thema besonders aufschlussreich fand, wurde in Mockitos Javadoc gefunden: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (siehe "2. Wie wäre es mit Stubbing?" ), verlinkt auf: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .
Bisher habe ich gerne mit Mockito gearbeitet, weil es dieses strenge Spottverhalten nicht erzwingt, sondern stattdessen Stubs verwendet. Es erzwingt auch die Methodenüberprüfung für bestimmte Objekte anstelle des gesamten Scheinobjekts. Am Ende überprüfen Sie nur die Methoden, die in Ihrem Testszenario wirklich wichtig sind.
Es gibt hier und da ein paar Bücher, die ich empfehlen kann, dieses Thema anzusprechen und spöttisch und allgemein:
xEinheitsmuster
Die Kunst des Unit Testing: Mit Beispielen in .Net
Java-Tests der nächsten Generation: TestNG und fortgeschrittene Konzepte (in diesem Buch geht es hauptsächlich um TestNG, aber es gibt ein nettes Kapitel über das Verspotten)
Answer.RETURNS_SMART_NULLS
Einstellung für Spott, die bei der Diagnose hilft.
Ich habe in meiner Erfahrung nur wenige Anti-Muster beobachtet.
Ansonsten war meine Erfahrung mit Mocks, insbesondere Mockito, ein Kinderspiel. Sie haben Tests sehr einfach zu schreiben und zu warten gemacht. Das Testen von Interaktionen zwischen GWT-Ansicht und Moderator ist mit Mocks viel einfacher als mit dem GWTTestCase.
Ich finde es besonders schwierig, Tests zu entschlüsseln und zu ändern, bei denen Mocks über mehrere Ebenen einer Anwendung hinweg verwendet werden. Ich denke jedoch, dass dies in den letzten Jahren durch verbesserte Mock-Framework-APIs gemildert wurde (ich verwende JMock, wo es angebracht ist).
Vor 5 oder 6 Jahren waren APIs wie EasyMock mächtig, aber sehr umständlich. Oft war der verwendete Testcode um Größenordnungen komplizierter als der getestete Code. Damals habe ich versucht, Teams zu beeinflussen, in denen ich sehr sparsam war, und mich mit einfachen handgefertigten Mocks zu begnügen, bei denen es sich lediglich um alternative Implementierungen von Schnittstellen handelte, die speziell für das Testen gedacht waren.
In letzter Zeit sind meine überzeugenden Meinungen dazu weicher geworden, da die spöttischen APIs Tests durchgeführt haben, in denen sie besser lesbar sind. Im Wesentlichen möchte ich, dass mein Code (einschließlich Tests) von anderen Entwicklern geändert werden kann, ohne dass sie das Gefühl haben, einen Sumpf dunkler API-Aufrufe zu durchlaufen.