2010-12-06 9 views
9

Ich bin gespannt, welche Methode Menschen gerne zum Mocking und warum verwenden. Die beiden Methoden, die ich kenne, verwenden hartcodierte Mock-Objekte und ein spöttisches Framework. Um dies zu demonstrieren, skizziere ich ein Beispiel mit C#.Hard-Coded Mock Objects vs Mocking Framework

Angenommen, wir haben eine IEmployeeRepository-Schnittstelle mit einer Methode namens GetEmployeeById.

public interface IEmployeeRepository 
{ 
    Employee GetEmployeeById(long id); 
} 

Wir können leicht spotten diese erstellen:

public class MockEmployeeRepository : IEmployeeRepository 
{ 
    public Employee GetEmployeeById(long id) 
    { 
     Employee employee = new Employee(); 
     employee.FirstName = "First"; 
     employee.LastName = "Last"; 
     ... 
     return employee; 
    } 
} 

Dann in unseren Tests können wir sagen, unsere Leistungen ausdrücklich MockEmployeeRepository, verwenden entweder eine Setter oder Dependency Injection verwenden. Ich bin neu in der Verspottung von Frameworks, deshalb bin ich neugierig, warum wir sie verwenden, wenn wir nur das Obige tun können?

+0

Hardcoding ist viel einfacher, wenn Sie keine Erfahrung mit dem Framework haben. Ein Framework ist leistungsfähiger, besonders wenn Sie Aussagen darüber machen wollen, ob eine Methode überhaupt oder zu oft aufgerufen wird. – k3b

Antwort

9

Das ist kein Mock, es ist ein Stub. Für Stubbing ist Ihr Beispiel durchaus akzeptabel.

Von Martin Fowler:

Mocks sind das, was wir reden hier: Objekte mit Erwartungen vorprogrammiert, die eine Spezifikation der Anrufe bilden sie erwartet, zu erhalten.

Wenn Sie etwas verspotten, rufen Sie normalerweise eine "Verify" -Methode auf.

Schauen Sie sich diese für die diff zwischen Mocks und Stubs http://martinfowler.com/articles/mocksArentStubs.html

+0

Sehr nützliche Informationen. Danke für den Link. –

+0

Wow, ich verstehe endlich den Unterschied zwischen einem Mock und einem Stub. – neuronet

2

Einige unterscheiden zwischen Mocks und Stubs. Ein Scheinobjekt kann verifizieren, dass es in der erwarteten Weise interagiert wurde. Ein spöttisches Framework kann es leicht machen, Mocks und Stubs zu erzeugen.

In Ihrem Beispiel haben Sie eine einzelne Methode in einer Schnittstelle ausgedruckt. Betrachten Sie eine Schnittstelle mit n Methoden, wobei sich n im Laufe der Zeit ändern kann. Eine Hand-Stub-Implementierung erfordert möglicherweise mehr Code und mehr Wartung.

1

Ich neige dazu, Stubs und Mocks zuerst von Hand zu schreiben. Wenn es dann einfach mit einem Mock-Objektrahmen ausgedrückt werden kann, schreibe ich es neu, so dass ich weniger Code zu pflegen habe.

1

Ich habe sie von Hand geschrieben. Ich hatte Schwierigkeiten, Moq zu benutzen, aber dann las ich TDD: Introduction to Moq, und ich glaube, ich verstehe jetzt, was sie über klassische vs. Ich werde Moq heute Abend noch einen weiteren Versuch geben, und ich denke, dass ich durch das Verständnis des "spöttischen" Ansatzes mir helfen kann, Moq besser für mich arbeiten zu lassen.

1

Eine gespottete Schnittstelle kann verschiedene Ausgaben pro Test haben - Ein Test kann eine Methode haben, die null zurückgibt, ein anderer Test hat die Methode ein Objekt zurückgeben, ein anderer Test hat eine Ausnahme. Dies ist alles im Komponententest konfiguriert, während Ihre Version mehrere handgeschriebene Objekte erfordern würde.

Psuedocode:

//Unit Test One 

MockObject.Expect(m => m.GetData()).Return(null); 

//Unit Test Two 

MockObject.Expect(m => m.GetData()).Return(new MyClass()); 

//Unit Test Three 

MockObject.Expect(m => m.GetData()).ThrowException(); 
4

Ich denke, die Wahl Dummy-Objekte von Hand zwischen dem Schreiben oder durch einen Rahmen mit einer Menge von den Arten der Komponenten abhängt, die Sie testen.

Wenn es Teil des Vertrags für die zu testende Komponente ist, mit ihren Mitarbeitern nach einem genauen Protokoll zu kommunizieren, dann sind instrumentierte Dummy-Objekte ("Mocks") genau das Richtige. Es ist häufig viel einfacher, solche Protokolle unter Verwendung eines Mocking-Frameworks als durch Handcodierung zu testen. Stellen Sie sich eine Komponente vor, die zum Öffnen eines Repositorys, zum Ausführen einiger Lese- und Schreibvorgänge in einer vorgegebenen Reihenfolge und zum Schließen des Repository erforderlich ist - selbst bei einer Ausnahme. Ein spöttisches Framework würde es einfacher machen, alle notwendigen Tests einzurichten. Anwendungen im Zusammenhang mit Telekommunikation und Prozesssteuerung (um ein paar zufällige Beispiele auszuwählen) sind voll von Komponenten, die auf diese Weise getestet werden müssen.

Auf der anderen Seite haben viele Komponenten in allgemeinen Geschäftsanwendungen keine besonderen Einschränkungen hinsichtlich der Kommunikation mit ihren Mitarbeitern. Stellen Sie sich eine Komponente vor, die eine Art Analyse von beispielsweise Universitätskursen durchführt. Die Komponente muss Instructor-, Student- und Kursinformationen aus einem Repository abrufen. Aber es spielt keine Rolle, in welcher Reihenfolge die Daten abgerufen werden: Lehrer-Schüler-Kurs, Schüler-Kurs-Lehrer, All-at-Once oder was auch immer. Es besteht keine Notwendigkeit, ein Datenzugriffsmuster zu testen und durchzusetzen. In der Tat wäre es wahrscheinlich schädlich, dieses Muster zu testen, da es eine bestimmte Implementierung unnötigerweise erfordern würde. In diesem Kontext sind einfache uninstrumentierte Dummy-Objekte ("Stubs") angemessen und ein spöttisches Framework ist wahrscheinlich zu viel.

Ich sollte darauf hinweisen, dass selbst wenn Stubbing, ein Framework immer noch Ihr Leben erleichtern kann. Man hat nicht immer den Luxus, die Unterschriften seiner Mitarbeiter zu diktieren. Stellen Sie sich vor, Sie testen eine Komponente, die für die Verarbeitung von Daten benötigt wird, die von einer dicken Schnittstelle wie IDataReader oder ResultSet abgerufen werden. Das Hand-Stubbing solcher Schnittstellen ist bestenfalls unangenehm - insbesondere dann, wenn die zu testende Komponente tatsächlich nur drei der zig Methoden in der Schnittstelle verwendet.

Für mich waren die Projekte, die Mockframeworks erforderten, fast ausnahmslos systemprogrammierender Natur (z. B. Datenbank- oder Webinfrastrukturprojekte oder Low-Level-Installation in einer Geschäftsanwendung). Bei Anwendungsprogrammierungsprojekten war meine Erfahrung, dass nur wenige Mocks in Sicht waren.

Angesichts der Tatsache, dass wir immer bestrebt sind, die chaotischen Low-Level-Infrastrukturdetails so gut wie möglich zu verstecken, scheint es, dass wir versuchen sollten, die einfachen Stubs weit über den Mocks zu haben.