Anstoßen Chained Methoden mit Rspec
-
21-08-2019 - |
Frage
Ich möchte ein named_scope aufzurufen, die nur einen Datensatz zurück, aber die named_scope ein Array zurückgibt, das ist keine große Sache, wie kann ich die Kette es nur mit .First:
Model.named_scope(param).first
und das funktioniert, was mit Ich kämpfe, wie der verkettete Aufruf Stummel. Hat jemand einen Verweis oder eine Antwort auf, wie ich über das Erreichen dieses mit Rspec spöttischen gehen würde?
Lösung
Ich dachte, etwas aus.
Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))
, die mir erlaubt, meinen Controller zu nennen:
@client = Client.named_scope(param).first
Es funktioniert, aber ist es eine bessere Lösung?
EDIT:
Die Veröffentlichung von rspec 1.2.6 ermöglicht es uns, das heißt zu verwenden stub_chain kann es nun sein:
Client.stub_chain(:named_scope, :chained_call).and_return(@clients = [mock(Client)])
Das war Spitze von meinem Kopf, wie immer die api für Einzelheiten überprüfen:)
Andere Tipps
Bessere Version von
Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))
wird sein:
Client.should_receive(:named_scope).with(param).and_return do
record = mock_model(Comm)
record.should_receive(:do_something_else)
[record]
end
Die Frage ist ziemlich alt und daher gibt es einige Verbesserungen, wie Anstoßen getan werden kann. Jetzt können Sie stub_chain Methode verwenden, um eine Kette von Methodenaufrufen Stummel. Zum Beispiel:
@client = Client.named_scope(param).first
kann mit Stub werden:
Client.stub_chain(:named_scope,:first).and_return(@client = mock(Client))
Weitere Beispiele für stub_chaining:
describe "stubbing a chain of methods" do
subject { Object.new }
context "given symbols representing methods" do
it "returns the correct value" do
subject.stub_chain(:one, :two, :three).and_return(:four)
subject.one.two.three.should eq(:four)
end
end
context "given a string of methods separated by dots" do
it "returns the correct value" do
subject.stub_chain("one.two.three").and_return(:four)
subject.one.two.three.should eq(:four)
end
end
end
Lange die rspecs leben !!! :)
Ich nehme an, dies ist in einem Controller spec?
sollten Sie Ihre eigenen Vorschlag funktionieren. Eine weitere Möglichkeit ist es, den named_scope Anruf in Ihrem Modell zu bewegen, um das Problem vollständig zu vermeiden. Dies würde auch mit der „Fett-Modellen, dünnen Controller“ Beratung entspricht.
Ich glaube, Sie haben bereits die dünnen Controller getan, indem die Abfrage in einen benannten Rahmen setzen, wo es wiederverwendet werden kann. Hier finden Sie einige Code, den ich verwendet, bevor ich mit Scopes gestartet.
def mock_comm(stubs={})
@mock_comm ||= mock_model(Comm, stubs)
end
describe "responding to GET index" do
it "should expose all comms as @comms" do
Comm.should_receive(:find).with(:all).and_return([mock_comm])
get :index
assigns[:comms].should == [mock_comm]
end
# ...
Ich würde wahrscheinlich Code ganz ähnlich schreiben, was Sie bereits, aber es vielleicht in einem Helfer setzen, dass ich es wieder verwenden kann. Die andere Sache ist, eine andere Mockframework zu verwenden, die vielleicht haben Sie mehr Kontrolle. Werfen Sie einen Blick auf Ryan Bates' Railscast auf RSpec - es ist ein bisschen alt geworden, aber immer noch einige gute Ideen drin
.