2009-08-17 6 views
9

Ich habe ein paar kleine fließende Schnittstellen durch Methodenverkettung erstellt. Sie rufen normalerweise eine Reihe von Repositorys auf, die Daten von Webservices/Datenbanken abrufen.Wie teste ich Unit-Testcode, der eine Fluent-Schnittstelle verwendet?

Wie sollte ich über Unit-Testmethoden gehen, die die fließende Schnittstelle verwenden?

Public IEnumberable<Computer> FindComputers(string serialNumber) 
{ 
     return Computers.FindBySerialNumber("YBCX00900") 
     .AttachConfiguration() 
     .EnsureAllComputersHaveConfiguration(); 
} 

Ich kann Einheit testen Sie die einzelnen Komponenten der Fluent Interface, aber wenn ich Unit-Test wollen die FindComputers Methode über das, was soll ich tun?

  1. über die konkrete Umsetzung der Fluent Interface und Erwartungen an den Repository-Klassen
  2. Mock die fließend Schnittstelle selbst und stellten auf diesem
  3. -Test nur die fließend Schnittstelle selbst und nicht die FindComputers Erwartungen schreiben() Methode

Ich möchte einen leicht zu wartenden Ansatz finden.

Antwort

3

Ich denke, dass der FI mehr tut, als es braucht. Ich nehme an, dass Sie Computer als Data Mapper verwenden und auch zum Erstellen einer Abfrage verwenden. Von dem, was Sie die Abfrage gezeigt haben, wird aus diesem aufgebaut:

rule 1: find configured computer with serial number = "whatever" and has-config = true. 
rule 2: find not-config computer with serial number = "whatever and has-config = true. 
rule 3: find configured computer with serial number = "whatever" and has-config = false. 
rule 4: find not-config computer with serial number = "whatever" and has-config = false. 
rule 5: find all computer with serial number = "whatever" and has-config = true. 
rule 6: find all computer with serial number = "whatever" and has-config = false. 

und so weiter ...

einige dieser Regeln Nun, die scheinen umgesetzt werden kann falsch zu sein. Regel 2 und Regel 3 scheinen miteinander zu kreuzen. Regel 5 und Regel 6 macht was? Ist das in Ordnung?

Weil Sie ein Objekt implementiert haben, das SRP bricht. Der erste Schritt besteht darin, den Abfrage-Generator vom Data Mapper zu trennen. Erstellen Sie Ihr FI-Abfrageobjekt, und übergeben Sie es an den Mapper.

Jetzt können Sie FindComputers testen, um sicherzustellen, dass das FI-Abfrageobjekt an einen Data Mapper gesendet wird. Da Sie jetzt ein FI-Query-Objekt erstellen können, können Sie es testen. Und Sie können testen, dass der Data Mapper ein Abfrageobjekt verwendet.

Was ist, wenn Sie in Zukunft Computer nach Standort suchen möchten? Wenn Sie den gleichen Code behalten, den Sie geschrieben haben, müssten Sie eine Methode hinzufügen FindByLocation und bevor Sie es wissen, haben Sie ein Gott-Objekt. stinkend!

+0

Danke, du hast Recht, das Beispiel ist schlecht durchdacht, ich habe seit dem FI in eins für die Abfrage, und eines, um Operationen an den zurückgegebenen Daten durchzuführen. Ich habe es am einfachsten gefunden, die FI einzeln zu testen, und dann Einheit Testmethoden, die die FI mit der konkreten Implementierung verwenden. Testen Sie einfach, dass das gewünschte Ergebnis zurückgegeben wird. Der Versuch, das FI zu verspotten, macht die Tests nur zu spröde. – Andronicus

0

Ich würde 2 + 3 tun. Unter der Annahme, dass die fließenden Schnittstellen echte Schnittstellen sind, sollten sie relativ einfach zu simulieren sein. Vergegenwärtigen Sie sich, dass jeder Schritt in der Aufrufkette wahrscheinlich ein neues Mock-Objekt zurückgibt, das wiederum den nächsten Aufruf in der Kette erwartet.

Sie sollten die fließende Schnittstelle immer noch direkt testen, indem Sie die darunter liegende Repository-Ebene mokieren.

+0

Danke für den Input, Ich dachte über die Fluent Interface spöttisch selbst, aber es scheint nur ungerade Tests zu schreiben wie ... Expect (x => x.FindBySerialNumber (null)).Return (nextMock) Expect (x => x.AttachConfiguration()) .Ret (nextMock) Wenn alle Tests durchgeführt werden, werden die Aufrufe tatsächlich ausgeführt. Es ist eine Menge Arbeit, die gesamte fließende Oberfläche in Mock-Objekten nachzubilden, nur um zu testen, was bereits klar in der zu testenden Methode geschrieben ist. – Andronicus

+0

Ich bin neu in der Unit-Testabdeckung und habe manchmal die gleichen Bedenken. Während es einfach ist, den Code durch Inspektion zu überprüfen, ist das noch manuelle Überprüfung. Das Hinzufügen einer Testabdeckung hilft Ihnen, die Straße zu schützen, wenn Sie nicht mehr an diese Klasse denken. Dies kann auch ein Hinweis darauf sein, dass die fließende Schnittstelle komplizierter ist, als wenn die Schnittstelle stärker auf das fokussiert wäre, was Sie benötigen. Die Tests wären auch einfacher zu schreiben. –

1

Können Sie Ihre Repositories verspotten? Während einige für einen reineren Ansatz plädieren, bei dem Sie eine Methode einer Klasse isolieren müssen, wäre es eine gute Möglichkeit zu testen, wie FindComputers und die fließende Oberfläche zusammenarbeiten. Und es kann einfacher sein, abhängig davon, wie die Repository-Zugriffsschicht aussieht.

Verwandte Themen