Ich versuche, die Tests in einer geerbten App zu verstehen, und ich brauche Hilfe.
Es gibt viele Spezifikationsgruppen wie diese (siehe Spezifikation):
%Vor% ... wobei job_post
eine auf dem Controller definierte Hilfsmethode ist. (Ja, sie hätten @instance-Variablen verwenden können, und ich bin dabei, sie zu refaktorisieren).
Nun, meiner Meinung nach ist die Verwendung von expect
in einem before
Block falsch. Lass uns das eine Sekunde vergessen.
Normalerweise ist der obige Test grün.
Wenn ich die Zeile expect
jedoch entferne , schlägt der Test fehl. Es scheint, dass in diesem Fall expect
die Methode in der Ansicht ausgibt. Tatsächlich scheint das Ersetzen von expect
durch allow
genau denselben Effekt zu haben.
Ich denke, was passiert, ist, dass normalerweise - wenn es mit einem Server läuft - die Ansicht job_posts
aufruft und die Nachricht land auf der Hilfsmethode auf dem Controller erscheint, was die erwartete ist Verhalten.
Hier setzt expect
jedoch eine Erwartung und stubbt gleichzeitig eine Methode für view
mit einem festen Rückgabewert. Da die Ansichtsvorlage diese Methode aufruft, wird der Test bestanden.
Über diesen unerwarteten "stub" Nebeneffekt von expect
habe ich das in der rspec gefunden -mocks readme :
(...) Wir können auch eine Nachrichtenerwartung festlegen, sodass das Beispiel fehlschlägt, wenn find nicht aufgerufen wird:
%Vor%RSpec ersetzt die Methode, die wir anstoßen oder verspotten, durch eine eigene Test-Doppel-ähnliche Methode . Am Ende des Beispiels überprüft RSpec alle Nachrichtenerwartungen und stellt dann die ursprünglichen Methoden wieder her.
Hat jemand Erfahrung mit dieser spezifischen Anwendung der Methode?
Nun, das macht expect().to receive()
! Dies ist die (nicht so) neue Erwartungssyntax von rspec
, die das should_receive
API
entspricht
%Vor%und diese API legt die Erwartung und den Rückgabewert fest. Dies ist das Standardverhalten. Um auch die ursprüngliche Methode aufzurufen , müssen Sie dies explizit sagen:
%Vor%Weiter zu einigen anderen Fragen:
(Ja, sie hätten @instance-Variablen verwenden können, und ich bin dabei, sie zu refaktorieren).
let
API ist in RSPC-Tests sehr allgegenwärtig und kann in vielen Fällen besser sein als @instance-Variablen (z. B. - es ist faul, also wird es nur ausgeführt, wenn es benötigt wird, und es ist memoisiert, also läuft es höchstens einmal).
Tatsächlich scheint das Ersetzen von
expect
durchallow
genau denselben Effekt zu haben.
Die allow
-Syntax ersetzt die stub
-Methode in der alten rspec-Syntax, also hat sie den gleichen Effekt, aber der Unterschied besteht darin, dass der Test nicht fehlschlägt, wenn die Stubbed-Methode ist nicht genannt.
Wie vom OP gefordert - einige Erklärungen zu should_receive
- Unit-Tests sollen isoliert ausgeführt werden . Dies bedeutet, dass alles, was nicht direkt Teil Ihres Tests ist, nicht getestet werden sollte. Dies bedeutet, dass HTTP-Aufrufe, E / A-Lesevorgänge, externe Dienste, andere Module usw. nicht Teil des Tests sind, und für den Zweck des Tests sollten Sie davon ausgehen Sie funktionieren korrekt.
Was Sie in Ihre Tests einbeziehen sollten, ist, dass diese HTTP-Aufrufe, IO-Lesevorgänge und externen Dienste korrekt aufgerufen werden. Dazu setzen Sie Nachrichtenerwartungen - Sie erwarten , dass die getestete Methode eine bestimmte Methode aufruft (deren tatsächliche Funktionalität außerhalb des Bereichs liegt der Test). Also erwarten Sie , dass der Service einen Methodenaufruf mit den richtigen Argumenten einmal oder mehrmals erhält (Sie können explizit erwarten, wie oft er aufgerufen werden sollte). Im Gegenzug dafür, dass es tatsächlich aufgerufen wird, stubst du es und setzt entsprechend dem Test seinen Rückgabewert.
Wenn Sie nicht als Nebeneffekt stubben möchten, können Sie immer das Original aufrufen.
Zum Beispiel wollte ich einmal eine Methode ausspionieren, aber auch die Funktion aufrufen, sonst hat sie andere Seiteneffekte. Das hat wirklich geholfen.
https://relishapp.com/rspec/rspec-mocks/v/2-14/docs/message-expectations/calling-the-original-method
Rspec ist ein Meta-Juwel, das von den rspec-core-, rspec-expectations- und rspec-mocks-Gems abhängt. Rspec-mocks ist ein Test-Double-Framework für rspec mit Unterstützung für Methoden-Stubs, Fälschungen und Nachrichtenerwartungen an generierten Test-Doubles und realen Objekten gleichermaßen.
%Vor%ist die Verwendung von 'Method Stubs', jedoch
%Vor%ist die Verwendung von 'Message Expectations'
Weitere Informationen finden Sie im Dokument .
Tags und Links ruby ruby-on-rails rspec rspec-mocks