2009-11-08 6 views
5

Okay, ich habe in letzter Zeit versucht, in IoC zu bekommen. Ich stoße jedoch immer wieder auf eine Hürde - das ist die Tatsache, dass ich gerne Mock-Objekte benutze.Best Practices für Unit-Tests, Mock-Objekte und IOC

Sie sind schnell und schmerzlos einzurichten.

Wenn ich IoC jedoch überall in meinem Code verwende, zwingt es mich, Testimplementierungen (und Konfigurationen) meiner Objekte zu erstellen, anstatt Mock-Objekte zu verwenden (zB mit moq).

Das Endergebnis ist, dass ich am Ende mit riesigen Konfigurationsdateien für das Testen.

Darüber hinaus gibt es viele Testszenarien, bei denen ich verschiedene Verhalten außerhalb meiner Klassen auf Test-zu-Test-Basis benötige. Mit moq Objekten ist das extrem einfach. Wie würdest du etwas ähnliches mit IoC machen?

Jede Hilfe würde sehr geschätzt werden.

Danke,
Mike

+0

Können Sie mehr Informationen über das Problem geben? Ich verstehe nicht, wie oder warum Sie ein Problem haben. Vielleicht ein Codebeispiel? –

+0

Wenn Sie eine Injektion verwenden, sollten die Abhängigkeiten in Ihrer Klasse normalerweise in den Konstruktor oder in die Eigenschaften eingefügt werden. In Ihrem Test sollten Sie also alle Nähte haben, die benötigt werden, um das zu ersetzen, was von Mocks injiziert wird. Können Sie einen konkreten Fall erläutern, mit dem Sie zu kämpfen haben? – Mathias

+0

Warum in aller Welt verwenden Sie einen IOC-Container für Unit-Tests? – mwjackson

Antwort

5

IoC sollte mit Mock-Objekte zu erleichtern, nicht erschweren.

Mehrere IoC-Container-Frameworks ermöglichen die Definition bereits vorhandener zu injizierender Objekte. mit Moq würden Sie es nur für myMockObject.Object einrichten.

EDIT: Beispiel Unity mit mock konfigurieren:

var mockService = new Mock<IMyService>(); 
container.RegisterInstance<IMyService>(mockService.Object); 

Als Alternative kann die Mockobjekt in den Konstruktor der Klasse unter Test bestehen nur (zum Konstruktor Injektion) und umgehen die IoC Behälter ganz in Ihren Unit-Tests.

EDIT: Joshs Antwort ist ein gutes Beispiel für die Alternative. Ich würde im Allgemeinen mit seiner Lösung gehen, anstatt den Container neu zu konfigurieren.

+0

Schön, wie man den IoC zum Testen benutzt. Am Ende mussten wir unseren eigenen IoC für die Verwendung mit WCSF aus einem Webkontext rollen. Es war überraschend einfach zu tun und endete als eine hervorragende Übung, um die Dependency Injection und IoC-Muster zu verstehen. – Josh

3

Ich liebe IoC, und ich liebe mich einige Mock-Objekte ...

Es gibt keinen Konflikt mit diesen beiden. Wenn Sie irgendeine Art von Dependency Injection durchführen, sollten Sie einfach Mock-Objekte mit Ihrem bevorzugten Mocking-Framework erstellen und diese dann an Ihr SUT übergeben.

[Test] 
public void AnAwesomeTest() 
{ 
    IDependencyOne d1 = MyMocker.Create<IDependencyOne>(); 
    IDependencyTwo d2 = MyMocker.Create<IDependencyTwo>(); 

    //Constructor injection 
    SUT sut = new SUT(d1); 

    //Property Injection 
    sut.DependantProperty = d2; 

    //Do some stuff and Assert 
} 
+0

+1. Beachten Sie, dass es "neue SUT (d1.Object)" mit Moq wäre. – TrueWill

+0

Interessant. Ich bin selbst an RhinoMocks gewöhnt ... wenn die Syntax das nicht weggibt. – Josh

+0

@Josh: Ein Unterschied ist, dass d1 und d2 vom Typ Mock sind. Downside muss tun. Object, um an die Schnittstelle zu gelangen, ist ups in der Lage, Erwartungen an d1 und d2 direkt zu setzen. Es lohnt sich, die Bibliotheken zu vergleichen/kontrastieren; Sie haben unterschiedliche Philosophien. Ich bin vor einiger Zeit von Rhino nach Moq gewechselt. – TrueWill