2010-11-23 3 views
3

Die Dinge begannen einfach mit meinen gefälschten Repositories, die hartcodierte Listen von Entitäten enthielten.ASP.NET MVC Komponententests - Gefälschtes Repository ist unhandlich geworden

Als ich Fortschritte gemacht habe, sind meine geteilten Fake-Repositories aufgebläht. Ich füge ständig neue Eigenschaften und neue Entitäten zu diesen Listen hinzu. Dies macht es extrem schwierig zu warten und es ist auch schwierig zu sehen, was der Test macht. Ich glaube, das ist ein Anti-Pattern namens "General Fixture".

Bei der Untersuchung von ASP.NET MVC-Komponententests habe ich zwei Methoden zur Vorbereitung von Repository-Fixtures kennengelernt, die an die Controller weitergegeben werden.

  1. erstellen hartcodierte gefälschte Repositories, die unter allen Tests
  2. Mock Teile der Repositories innerhalb der einzelnen Test geteilt werden

Ich bin versucht Option # 2 oben zu erkunden, aber ich habe gelesen Es ist keine gute Idee, Repositories nachzuahmen, und es erscheint ziemlich entmutigend in den Szenarien, in denen ich einen Controller teste, der mit Sammlungen arbeitet (dh mit Paging-/Sortier-/Filterfunktionen).

Meine Frage an die Community ...

Welche Verfahren zur Herstellung von Repository Vorrichtungen über rudimentäre Beispiele gut funktionieren?

Antwort

2

Ich denke nicht, dass Sie nur eine der beiden Optionen wählen sollten. Es gibt Fälle, in denen die Verwendung eines gefälschten Repositorys besser wäre, und es gibt Fälle, in denen das Spotten besser wäre. Ich denke, Sie sollten von Fall zu Fall beurteilen, was Sie brauchen. Wenn Sie beispielsweise einen Test für eine UsersService schreiben, die eine IUserRepository.DoesUserExist() aufrufen muss, die einen booleschen Wert zurückgibt, dann würden Sie kein gefälschtes Repository verwenden. Es ist einfacher, einen Aufruf zu verfälschen, um wahr oder falsch zurückzugeben.

Moq ist genial.

+0

Das waren alles großartige Antworten. Ich benutze Moq, seit ich diese Frage gestellt habe, um Repositories für einzelne Tests nachzubilden, und es funktioniert gut. Ich glaube, es ist sinnvoll, beide Methoden wie von Ihnen vorgeschlagen zu verwenden. Ich finde es auch nützlich, Routinen zu erstellen, die Daten zur Verwendung mit den Mocks generieren - auf diese Weise binde ich keinen Code, um diese Daten zu erzeugen, aber die Daten werden auch nicht geteilt. :) – Mayo

2

Aus einem ähnlichen Grund für ein neues Projekt bin ich mit einem ORM (NHibernate in meinem Fall). Auf diese Weise kann ich es auf eine "in-memory" SQLLite-Instanz (anstatt SQL Server) zeigen und es sollte viel einfacher zu installieren/zu warten sein (ich hoffe). Auf diese Weise muss ich nur das Repository verspotten, wenn ich bestimmte Szenarien testen muss (z. B. Timeouts usw.)

2

Wenn Sie Ihre Komponententests für TDD verwenden, laden Sie Rhino Mocks herunter und verwenden Sie Option 2.

+0

Es gibt auch MOQ (http://code.google.com/p/moq/), die ich für # 2 verwendet habe. Ich finde das auch ziemlich sperrig und zeitaufwendig, weshalb ich auf den ORM-Winkel schaue. –

1

Zum größten Teil gehen wir mit testspezifischen Repository-Mocks. Ich habe nie einen Rat gesehen, das nicht selbst zu tun, und ich finde, dass es großartig funktioniert. Unsere Repository-Methoden und daher auch unsere Mocks geben meistens nur einzelne Modelle oder Listen von Modellen (nicht Datenkontexte) zurück, so dass es einfach ist, die spezifischen Daten für jeden Test zu erstellen und für jede Abfrage isoliert zu erstellen. Das bedeutet, dass wir beliebige Daten nachahmen können, ohne andere Tests oder Abfragen im selben Test zu beeinträchtigen. Es ist sehr einfach zu sehen, warum die Daten erstellt wurden und was sie testet.

Ich war auf Teams haben auch beschlossen, von Zeit zu Zeit auch gemeinsame Mock-Daten zu erstellen. Ich denke, die Entscheidung wurde im Allgemeinen getroffen, weil die Routinen dynamische Abfragen erzeugten und die Daten, die erforderlich waren, um alle Tests nachzuahmen, dazu führten, dass ein guter Teil der Datenbank dupliziert wurde. Rückblickend hätte ich wahrscheinlich vorgeschlagen, dass nur die resultierenden Abfragen überprüft werden müssen, nicht die Inhalte, die von der Datenbank zurückgegeben werden. Und somit würden überhaupt keine Daten verspottet werden, es hätte einige Codeänderungen erforderlich gemacht. Ich erwähne das nur, um zu verdeutlichen, dass, wenn Sie nicht einen Weg finden können, um Option 2 zum Laufen zu bringen, es vielleicht eine Möglichkeit gibt, den Code umzuformulieren, um ihn testbarer zu machen.