Stubbing Méthodes Chained avec Rspec
-
21-08-2019 - |
Question
Je veux appeler un named_scope qui ne renverra un enregistrement, mais le named_scope retourne un tableau, ce n'est pas une grosse affaire que je peux enchaîner avec .first:
Model.named_scope(param).first
et cela fonctionne, ce que je me bats avec est de savoir comment stub l'appel enchaîné. Quelqu'un at-il une référence ou une réponse sur la façon dont je vaquer à atteindre cet objectif avec Rspec moqueur?
La solution
Je me suis dit quelque chose.
Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))
ce qui me permet d'appeler mon contrôleur:
@client = Client.named_scope(param).first
Il fonctionne, mais est-il une meilleure solution?
EDIT:
La libération de rspec 1.2.6 nous permet d'utiliser ce qui signifie stub_chain il peut maintenant être:
Client.stub_chain(:named_scope, :chained_call).and_return(@clients = [mock(Client)])
C'était haut de ma tête, comme toujours vérifier le api pour plus de détails:)
Autres conseils
meilleure version de
Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))
sera:
Client.should_receive(:named_scope).with(param).and_return do
record = mock_model(Comm)
record.should_receive(:do_something_else)
[record]
end
La question est assez vieux et donc il y a quelques améliorations dans la façon dont stubbing peut être fait. Maintenant, vous pouvez utiliser la méthode stub_chain pour bouchonner une chaîne d'appels de méthode. Par exemple:
@client = Client.named_scope(param).first
peut être bouchonné avec:
Client.stub_chain(:named_scope,:first).and_return(@client = mock(Client))
D'autres exemples de 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
ou s'il vous plaît jeter un oeil à:
Vive les rspecs !!! :)
Je suppose que cela est dans une spécification du contrôleur?
Votre propre suggestion devrait fonctionner correctement. Une autre possibilité est de passer l'appel named_scope dans votre modèle, afin d'éviter la question tout à fait. Ce serait également conforme à l'avis « modèles de graisse, les contrôleurs minces ».
Je pense que vous avez déjà fait la chose mince contrôleur en mettant la requête dans un champ nommé où il peut être réutilisé. Voici un code je avant que je commencé à utiliser named scopes.
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
# ...
Je serais probablement écrire un code assez similaire à ce que vous avez déjà, mais peut-être mis dans une aide qui me permet de le réutiliser. L'autre chose est d'utiliser un cadre moqueur différent qui vous donne peut-être plus de contrôle. Jetez un oeil à la Railscast de Ryan Bates sur RSpec - c'est un peu vieux maintenant, mais encore quelques bonnes idées là-dedans
.