在rails中使用rspec模拟/存根控制器重新绑定方法

时间:2014-08-17 14:05:57

标签: ruby-on-rails unit-testing rspec

我正在学习如何使用存根和模拟,我想模拟下面的verify_recaptcha方法来测试条件的两种结果。

我的控制器代码(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

我的规格到目前为止

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

为了存根/模拟出verify_recaptcha,我应该把上面的内容放在哪里?我试过了DogMailsController.stub(:verify_recaptcha).and_return(false),但似乎没有用。

2 个答案:

答案 0 :(得分:1)

默认情况下,Recaptcha宝石hide the widget in test的最新版本(我认为是3.2+),因此比起Recaptcha成功,您更有可能最终需要模拟Recaptcha故障。如果您直接测试Rails控制器,则可以使用infused's answer above的变体:

expect(controller).to receive(:verify_recaptcha).and_return(false)

如果您使用的是Rails 5系统或要求提供规格,则可能需要使用expect_any_instance_of

expect_any_instance_of(MyController).to receive(:verify_recaptcha).and_return(false)

您也可以使用

expect_any_instance_of(Recaptcha::Verify)

请注意,尽管在某些情况下(例如服务器超时),verify_recaptcha会提高Recaptcha::RecaptchaError而不是返回false,所以您可能还需要进行测试-如上所述,但替换

and_return(false)

使用

and_raise(Recaptcha::RecaptchaError)

(碰巧的是

答案 1 :(得分:0)

你只需要存根controller.verify_recaptcha,所以使用RSpec 3语法:

allow(controller).to receive(:verify_recaptcha).and_return(true)