2012-05-31 6 views
21

Ich bin nur neugierig, wo Leute FactoryGirl.build_stubbed verwenden und wo sie double beim Schreiben von RSpec-Spezifikationen verwenden. Das heißt, gibt es Best Practices wie "Verwenden Sie nur FactoryGirl-Methoden in den entsprechenden Modellspezifikationen?"Wo `FactoryGirl.build_stubbed` zu verwenden ist und wo RSpec`s` mock`/`double` zu ​​verwenden ist

Ist es ein Code-Geruch, wenn Sie sich mit FactoryGirl.create(:foo) in spec/models/bar_spec.rb finden?

Ist es weniger ein Code-Geruch, wenn Sie FactoryGirl.build_stubbed(:foo) in spec/models/bar_spec.rb verwenden?

Ist es ein Code-Geruch, wenn Sie FactoryGirl.create(:foo) in foos_controller_spec.rb verwenden?

Ist es weniger ein Code-Geruch, wenn Sie FactoryGirl.build_stubbed(:foo) in foos_controller_spec.rb verwenden?

Ist es ein Code-Geruch, wenn Sie FactoryGirl.build_stubbed(:foo) in spec/decorators/foo_decorator_spec.rb verwenden?

Sorry für so viele Fragen! Ich würde einfach gerne wissen, wie andere Leute die Grenzen in der Best Practices für Komponententests und objektorientierte Designs ziehen.

Danke!

+0

Ich persönlich wusste nicht einmal über 'FactoryGirl.build_stubbed'. Wahrscheinlich erklärt dies fehlende Antworten. Dies oder eine hohe Subjektivität des Begriffs "Code-Geruch". –

Antwort

17

Ich glaube, dass es Best Practices gibt, die uns dazu bringen, darüber nachzudenken, wann man Mocks (in diesem Fall "verdoppelt") gegen echte Abhängigkeiten (in diesem Fall "Factories") verwenden sollte. Es gibt ein wirklich gutes Buch zum Testen (Achtung: es verwendet Java-Beispiele), das den Zweck der testgetriebenen Entwicklung beschreibt, und ich denke, es ist sehr hilfreich in dieser Diskussion über das Testen in Rails-Anwendungen. Es beschreibt die Absicht zu testen wie folgt:

... unsere Absicht in Test-driven Entwicklung ist, Mock-Objekte zu verwenden, um Beziehungen zwischen Objekten hervorzubringen.

Freeman, Steve; Pryce, Nat (2009-10-12). Wachsende objektorientierte Software, geleitet von Tests (Kindle Locations 3878-3879). Pearson Ausbildung (USA). Kindle Edition.

Wenn wir diesen Schwerpunkt denken über die Verwendung testgetriebene Entwicklung nicht nur uns von der Einführung Regressionen zu verhindern, aber wir darüber nachdenken, zu helfen, wie unser Code in Bezug auf seine Oberfläche aufgebaut ist und Beziehungen zu anderen Objekten werden wir natürlich Mocks in vielen Fällen verwenden. Ich werde beschreiben, wie dies für Ihre spezifischen Fragen unten gilt.

Erstens, in Bezug darauf, ob wir Mock-Objekte oder reale Abhängigkeiten in Modelltests verwenden - wenn wir Klasse Foo und seine Abhängigkeit von Bar testen, möchten wir vielleicht einen Schein für Bar ersetzen. Auf diese Weise werden wir deutlich die Ebene der Kopplung mit Bar sehen, da wir uns über die Methoden lustig machen müssen, die danach benannt werden. Wenn wir feststellen, dass unser Spott von Bar komplex ist, ist das ein Zeichen dafür, dass wir Foo und Bar vielleicht so umgestalten sollten, dass sie weniger miteinander verbunden sind. In dem Sinne, dass sowohl Factory.create als auch Factory.build_stubbed den gleichen Effekt haben, Abhängigkeiten von verwandten Klassen nicht explizit zu machen, denke ich, dass sie beide so stinkend sind, dass Factory.create die langsamere der beiden Optionen ist.

In meinen Tests tendiere ich mich nicht zu viel Gedanken über externe Abhängigkeiten in Controllern.Ich weiß, dass das langsamer ist als das vollständige Spotten, und Sie haben nicht den Vorteil, dass der Controller explizit mit dem Modell koppelt, aber es ist schneller, den Test zu schreiben, und ich mache mir im Allgemeinen nicht so große Sorgen Beziehung zwischen Controllern und den von ihnen verwalteten persistenten Datensätzen. Solange du den Mustern von "mageren Controllern" folgst, sollte es nicht zu logisch sein, sich hier irgendwie zu sorgen. Wenn wir einen Grad von "Testgeruch" angeben müssen, würde ich sagen, dass es ein wenig weniger stinkt als Modelltests, die von anderen Fabriken abhängen.

Ich würde mich am wenigsten Sorgen machen über Decorators, die Fabriken der Klassen abhängen, die sie dekorieren. Dies liegt daran, dass der Dekorator per Definition dieselbe Schnittstelle wie die von ihm dekorierte Klasse beibehalten sollte. Dekoration wird meistens mit irgendeiner Form von Vererbung implementiert, sei es durch Verwendung von method_missing, um an den Verzierten zu delegieren, oder durch explizite Unterklassenbildung des Verzierers. Aus diesem Grund brechen Sie andere Regeln der guten objektorientierten Programmierung wie Likov Substitution, wenn der Dekorateur zu sehr von der Schnittstelle der Sache abweicht, die er schmückt. Solange Ihre Dekoration nicht schlecht umgesetzt wird, indem Sie die Regeln der guten Vererbung brechen, ist die Kopplung mit der Klasse, die Sie dekorieren, bereits vorhanden, so dass es die Dinge nicht viel schlimmer macht, wenn Sie den Test von einem persistent oder stubed abhängen Fabrik der Sache, die es schmückt. Sie können verrückt mit Fabriken in Decorator Tests und es spielt keine Rolle, IMO.

Ich denke, dass es wichtig ist zu beachten, dass selbst wenn Sie Mocks in den meisten Fällen bevorzugen, Sie noch einige Integrationstests haben sollten, die echte Abhängigkeiten verwenden. Sie werden feststellen, dass diese spezielle Fälle mit hohem Wert abdecken, bei denen die isolierten Komponententests mehr Funktionalität für Ihre Klassen bieten.

In jedem Fall breche ich alle oben genannten Regeln manchmal und sie sind nur einige Richtlinien, die ich in schriftlichen Tests verwende. Ich freue mich darauf zu hören, wie andere Factories (build_stubbed und wirklich persistent) gegen Mock-Objekte (doubles) in ihren Tests einsetzen.

+1

Super Zeug! Schätze es wirklich. Über Integrationstests in Rails - auf welcher Ebene testen Sie, ob unterschiedliche Objekte tatsächlich die korrekten Schnittstellen anderer Objekte verwenden? Die Beispiele, die ich immer sehe, sind Tests auf Browser-Ebene (Capybara, Selen usw.). Gibt es eine gute Möglichkeit, spezifischere Integrationstests (zwischen Modellen) durchzuführen? Oder sollte das überhaupt nötig sein? –

Verwandte Themen