问题
I'm just learning how to use stubs and mocks and I would like to mock out the below verify_recaptcha
method to test both outcomes of the condition.
my controller code (DogMailsController)
if verify_recaptcha(:model=>@email,:message=>"Verification code is wrong", :attribute=>"verification code")
if DogMail.make_mail dog_mail_params
result = "success"
else
result = "fail"
end
else
flash.delete(:recaptcha_error)
flash.now[:error] = "Validation Failed. Please enter validation numbers/letters correctly at bottom."
render :action => 'new', :locals => { :@email => DogMail.new(dog_mail_params)}
end
end
My spec so far
context "when master not signed in" do
context "when recaptcha verified" do
context "with valid params" do
it "should save the new dog mail in the database" do
expect{
post :create, dog_mail: attributes_for(:dog_mail)
}.to change(DogMail, :count).by(1)
end
end
context "with invalid params" do
end
end
What should I put above expect inorder to stub/mock out verify_recaptcha? I tried DogMailsController.stub(:verify_recaptcha).and_return(false)
but it doesn't seem to work.
回答1:
You just need to stub controller.verify_recaptcha
, so with RSpec 3 syntax:
allow(controller).to receive(:verify_recaptcha).and_return(true)
回答2:
Recent versions (3.2+ I think) of the Recaptcha gem hide the widget in test by default, so you're more likely to end up needing to mock a Recaptcha failure than a Recaptcha success. If you're testing a Rails controller directly, you can use a variant of infused's answer above:
expect(controller).to receive(:verify_recaptcha).and_return(false)
If you're in a Rails 5 system or request spec, you may need to use expect_any_instance_of
:
expect_any_instance_of(MyController).to receive(:verify_recaptcha).and_return(false)
You could also use
expect_any_instance_of(Recaptcha::Verify)
Note though that there are also situations (e.g. a server timeout) in which verify_recaptcha
will raise Recaptcha::RecaptchaError
instead of returning false, so you may want to test for those as well -- as above, but replace
and_return(false)
with
and_raise(Recaptcha::RecaptchaError)
(As it happens, this will also
来源:https://stackoverflow.com/questions/25349927/mocking-stubbing-a-controller-recaptcha-method-with-rspec-in-rails