2008-11-18 11 views
38

Kürzlich gab es einen Hype um all die verschiedenen Mock-Frameworks in der .NET-Welt. Ich habe immer noch nicht begriffen, was an ihnen so großartig ist. Es scheint mir nicht schwer zu sein, die spöttischen Objekte zu schreiben, die ich selbst brauche. Vor allem mit Hilfe von Visual Studio kann ich schnell eine Klasse schreiben, die die Schnittstelle implementiert, die ich simulieren möchte (es erzeugt fast alles automatisch für mich) und dann eine Implementierung für die Methode (n) schreiben, die ich für meinen Test brauche. Erledigt! Warum sollten Sie sich die Mühe machen, einen spöttischen Rahmen zu verstehen, nur um ein paar Zeilen Code zu speichern? Oder spottet man nicht nur Codezeilen?Warum brauche ich ein Spottframework für meine Unittests?

+3

Nur ein Vorbehalt ... diese Frage ist nicht .NET-spezifisch. Also lesen Sie weiter, wenn Sie sich irgendwie hier gefunden haben. – smp7d

Antwort

32

Sobald ich endlich den Überblick über Mock-Objekte bekam, erkannte ich, dass sie für Unit-Tests aus demselben Grund unentbehrlich sind wie Doppelblind-Test- oder Kontrollgruppen: Sie isolieren, was Sie gerade testen.

Wenn Sie eine Klasse testen, die ziemlich viel Interaktion über andere Schnittstellen hat, speichern Sie nicht nur die Codezeilen, indem Sie jede einzelne Schnittstelle überspielen müssen, sondern Sie erhalten auch die Möglichkeit, Dinge wie " Eine Exception auslösen, wenn eine unerwartete Methode "oder" Exception aufgerufen wird, wenn diese Methoden nicht in der richtigen Reihenfolge aufgerufen werden ". Sie können erstaunlich komplex mit Scheingerüsten arbeiten, und obwohl ich schnell zugeben werde, dass es eine große Lernkurve gibt, werden Sie, wenn Sie auf dem Laufenden sind, dazu beitragen, dass Ihre Komponententests gründlicher werden, ohne aufgebläht zu werden.

+0

Wie können Methoden aufgerufen werden außer Betrieb? IMO, es ist ein Code-Geruch. –

+1

Hängt vom Workflow der Klasse unter Mock ab. Wenn ein Zustand über einen bekannten Lebenszyklus beibehalten wurde (z. B. init(), run(), teardown()), muss die getestete Klasse diesen Zustand berücksichtigen. –

+1

Geht das nicht ein bisschen zurück? Einen Anrufer dafür verantwortlich machen, dass jemand anderen den richtigen Zustand hat? Sollte nicht die Klasse, die eine ordnungsgemäße Rufreihenfolge benötigt, dafür sorgen, dass sie korrekt aufgerufen wird? Durch das Auslösen von Ausnahmen/Behauptungen, wenn dies nicht der Fall ist? Und sollten die Tests für diese "order-requiring-class" nicht überprüfen, dass sie ausgelöst werden, wenn Methoden in einer ungeeigneten Reihenfolge aufgerufen werden? Es scheint mir, dass dies ein effektiverer Weg wäre, um die Verantwortung für den richtigen Gebrauch auf alle möglichen Benutzer dieser "Ordnung erfordernden Klasse" zu mischen. –

3

Nun, ich denke sicherlich nicht, dass Sie einen spöttischen Rahmen brauchen. Es ist ein Framework wie jedes andere, und es wurde letztlich entwickelt, um Ihnen etwas Zeit und Mühe zu sparen. Sie können auch eigene allgemeine Datenstrukturen wie Stacks und Queues erstellen, aber ist es nicht generell einfacher, nur diejenigen zu verwenden, die in den Klassenbibliotheken enthalten sind, die mit dem Compiler/IDE Ihrer Sprache geliefert werden?

Ich bin mir sicher, es gibt andere zwingende Gründe für die Verwendung von Mocking Frameworks, obwohl ich es den TDD und Unit Testing Gurus überlassen würde zu antworten.

4

Roy Osherove hatte eine Umfrage über Mock Frameworks und unten im Kommentarbereich gibt es eine Diskussion (wenn auch kurz) darüber, ob man ein Mock Framework braucht oder nicht.

Ich persönlich habe manuell genau das getan, was Sie gesagt haben, und es hat gut genug funktioniert, aber das war hauptsächlich aus Gewohnheit, anstatt einer eng gefassten Meinung zu Mock-Frameworks im Allgemeinen.

8

Zurück Fragen, die helfen können:
What is a mock and when should you use it?
Mockist vs classical TDD

Ich finde, dass ein Mockframework mit mir erlaubt, Tests viel schneller zu erzeugen und mit einer besseren Überprüfung, was ich eigentlich im Test passieren erwarten ist passiert. Ich habe in der Vergangenheit Stubs oder Fälschungen selbst implementiert. Ich fand, dass ich Stubs erzeugen musste, die spezifisch für den Test waren, den ich wollte, und das nahm viel Zeit in Anspruch. Ich kann den gleichen Test viel schneller mit einem spöttischen Framework erstellen. Die Guten unterstützen die Generierung von Fälschungen, Stubs oder Mocks mit direkter Syntax.

Es dauert eine Weile, um den Dreh raus zu bekommen, ich vermied es für eine Weile, aber jetzt würde nicht versuchen, ohne einen spöttischen Rahmen zu arbeiten, aus den Gründen @ Chamelaeon Staaten.

+1

+1 Man könnte fast sagen, ein spöttisches Framework bietet ein DSL - und die Vorteile von DSL sind gut verstanden. –

12

Sie haben tatsächlich einen der wichtigsten Punkte eines Mock-Frameworks in Ihrer Frage identifiziert. Die Tatsache, dass Sie die Mocks selbst codieren, sollte der Entwickler nicht beachten. Die Mocking-Frameworks geben Ihnen programmtechnische Implementierungen von Schnittstellen, und sie sind funktional (basierend auf Ihrer Einrichtung des Mocks).

Was tun Sie, wenn Sie beispielsweise ein ICustomerDAO testen und eine Methode 14 Mal mit unterschiedlichen Ergebnissen testen möchten? 14 verschiedene Klassen manuell implementieren? Ich bezweifle, dass irgendjemand das machen möchte.

Mocks geben Ihnen die Möglichkeit zu definieren, was mit Teilen Ihrer Klassen passiert, wenn Sie nicht daran interessiert sind, ob sie tatsächlich funktionieren oder nicht, wie Ausnahmen auslösen, wann immer Sie wollen, null Ergebnisse zurückgeben und sichergehen das richtig, etc ...

Sie sind ein großes Gerät Test-Tool.

0

Eines der guten Dinge an einem spöttischen Framework ist, dass es erlaubt, Erwartungen an die Objekte zu stellen, die verspottet werden. Mit den Erwartungen kann ich dann alle möglichen Bedingungen schaffen, um den Code auszuprobieren, der getestet wird.

2

Aus dem gleichen Grund würden Sie nicht versuchen, Komponententests ohne NUnit zu schreiben. Ein spöttisches Framework unterstützt Sie bei der Überprüfung von Status und Verhalten bei Hunderten von Komponententests. Es ist die zwei Wochen oder so Schmerzen wert, um auf dem neuesten Stand zu sein und wirklich hilft Ihnen, sich auf das zu konzentrieren, was getestet werden muss.

0

Ein Isolierungsframework oder mocking framework ermöglicht es Ihnen, den gewünschten Code ohne seine Abhängigkeiten zu testen. Es ermöglicht kurze Tests, ermöglicht schnelles Debuggen und vereinfacht das Erstellen von Sicherheitsnetzwerken für den Code. Verschiedene Frameworks haben unterschiedliche Funktionen, und wie bereits gesagt - es ist ein Werkzeug, und Sie sollten das richtige Werkzeug für den Job auswählen.

2

Eine Sache, die mich von einem Mockframework beunruhigt ist, dass "was für eine Funktion sollte o/p ein i/p gegeben" über

wenn (mock.someMethod ("some arg")). ThenReturn ("etwas");

Anweisung ist über viele Unit-Test-Klassen verteilt.

Lassen Sie mich mit einem Beispiel erläutern. Nehmen wir an, es gab eine DAO-Schnittstellenfunktion getEmp (int EmpID), die ein Employee-Objekt zurückgab, wenn eine Mitarbeiter-ID als Parameter übergeben wurde. Angenommen, diese Funktion wurde von 10 verschiedenen Unit-Test-Klassen verspottet. Wenn diese Funktion in Zukunft geändert würde, um eine neuere Version des Employee-Objekts zurückzugeben, müsste man zu jeder der 10 verschiedenen Klassen wechseln, um diese Änderung zu aktualisieren.

Die Nachteile sind wie folgt ...

a) Ich weiß nicht, wie alle Klassen, die diese Funktion verspotten, um herauszufinden, so dass ich diese Änderung aktualisieren gehen kann.

b) Meine vorhandenen Testfälle, die das Mock-DAO-Objekt konsumieren, sind sich der Änderungen, die mit der DAO-Schnittstelle passiert sind, weiterhin nicht bewusst, da sich der Schein nicht geändert hat und daher weiterhin grün ist. Idealerweise hätte ich nur eine Stelle für die neuere Version des Employee-Objekts, wenn ich eine einzelne Scheinklasse selbst codiert und überall verbraucht hätte. Sobald ich an diesem einen Ort aktualisiert habe, würden alle meine existierenden Testfälle, die den Mock konsumieren, kaputt gehen und ich würde dann genau wissen, welche Orte ich brauche, um ein Update für das neue Mitarbeiterobjekt zu machen.

Irgendwelche Gedanken über meine Ansichten ..

0

I Verwendung Nashorn haben spottet für einen Mockframework. Ich und 5 andere Entwickler verwendeten es in einer großen Unternehmensanwendung, die ein 8-monatiges Projekt war. Wir haben TDD für das Projekt verwendet. War es das wert? Ich vermute.Gab es so ein riesiges Verkaufsargument für die Verwendung von Mocks, dass ich es bei jedem Projekt verwenden muss? Meiner Meinung nach, nein. Es ist nicht etwas, das notwendig ist, es ist nur ein Werkzeug, das Sie verwenden können, wenn Sie es ausprobieren möchten. Bei einigen Projekten kannst du deine eigenen Scheinklassen einführen, da einige hier angeben, dass sie es bevorzugen - es ist einfacher. Andere Projekte sind größer und erfordern möglicherweise einen spöttischen Rahmen. Das Schlüsselwort (meiner Meinung nach) ist MAI erfordern ... wie viel Code Abdeckung benötigen Sie? Das ist für mich eine weitere Überlegung, Mocks zu verwenden. Bei dem Projekt, das ich mit tdd/rhino mocks gemacht habe, mussten wir eine 80% ige Codeabdeckung haben, damit die Mocks uns dabei unterstützen konnten. Wenn unsere Anforderungen an die Codeabdeckung geringer wären, zum Beispiel 40%, hätten wir wahrscheinlich kein spöttisches Framework verwendet und einfach unsere eigenen Scheinklassen geschrieben, wie andere es erwähnen.

Verwandte Themen