【问题标题】:Rspec problem mocking model in controller控制器中的Rspec问题模拟模型
【发布时间】:2011-03-18 14:17:50
【问题描述】:

我设置了一个控制器来处理omniauth 身份验证,这些身份验证被用于自定义构建的身份验证系统。我正在尝试测试如何处理身份验证的逻辑(例如:如果用户已经拥有/没有帐户,如果用户当前/未登录等)。因此,我有一个授权模型和一个授权控制器。创建授权的操作大致如下:

class AuthorizationsController < ApplicationController 

  def create  
    omniauth = request.env['omniauth.auth']
    authorization = Authorization.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
    if authorization
      # Authorization already established, log in user
    elsif current_user
      # User is logged in but wants to add another omniauth authentication
    else
      # Create user and associate them with omniauth authentication
    end
  end

end

我正在尝试在 Rspec 中测试此逻辑,但遇到了问题。这是我在规范中使用的内容:

describe AuthorizationsController do
  render_views

  describe "POST 'create'" do

    describe "with an already existing authorization" do

      it "should log the user in" do
        @authmock = mock_model(Authorization)
        Authorization.should_receive(:find_by_provider_and_uid).and_return(@authmock)
        post :create, :provider => 'twitter'
        current_user?(@authmock.user).should == true
        response.should redirect_to(root_path)
      end
    end
  end
end

我的印象是,当进行赋值调用时,这应该将我的模拟授权模型 (@authmock) 分配给我的控制器中的局部变量授权,从而使“如果授权”返回 true。但是,每当我真正运行此规范时,我都会收到此错误:

Failures:

  1) AuthorizationsController POST 'create' with an already existing authorization should log the user in
     Failure/Error: post :create, :provider => 'twitter'
     NoMethodError:
       You have a nil object when you didn't expect it!
       You might have expected an instance of Array.
       The error occurred while evaluating nil.[]
     # ./app/controllers/authorizations_controller.rb:5:in `create'
     # ./spec/controllers/authorizations_controller_spec.rb:16:in `block (4 levels) in <top (required)>'

谁能告诉我我在这里做错了什么?

编辑:

由于提出了关于omniauth 的分配是否导致问题的问题,我注释掉了该行以查看会发生什么并得到以下错误:

  1) AuthorizationsController POST 'create' with an already existing authorization should log the user in
     Failure/Error: post :create, :provider => 'twitter'
     NameError:
       undefined local variable or method `omniauth' for #<AuthorizationsController:0xb41809c>
 # ./app/controllers/authorizations_controller.rb:5:in `create'
 # ./spec/controllers/authorizations_controller_spec.rb:16:in `block (4 levels) in <top (required)>'

这告诉我问题出在模拟或存根上,因为 find_by_provider_and_uid 函数仍在评估中,并且在测试运行时没有存根

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 tdd mocking rspec


    【解决方案1】:

    你在指定

    current_user?(@authmock.user).should == true
    

    response.should redirect_to(root_path)
    

    我认为不应该在这里测试第一个期望,因为你已经模拟了“如果授权”块,所以你应该指定接下来会发生什么!

    【讨论】:

    • 指出。问题是尽管测试永远不会到达这一点,因为它在'authorization = Authorization.find_by_provider_and_uid(omniauth['provider'],omniauth['uid'])'
    • Wierd ...看起来它没有存根方法并尝试使用omniauth哈希评估真正的find_by_provider_and_uid方法,在您的情况下为null,对吗? omn​​iauth = request.env['omniauth.auth']
    • 据我所知,这似乎是问题所在
    • 啊…… request.env 在这里为空!这看起来像个问题
    • 我不认为这是问题,因为局部变量只是设置为 nil,这不应该是一个问题。在第 5 行也抛出了错误,这意味着对 request.env 的分配可以正常进行。然而,我确实评论了这条线只是为了看看会发生什么并在编辑中发布它
    猜你喜欢
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    相关资源
    最近更新 更多