代码之家  ›  专栏  ›  技术社区  ›  JoseMarmolejos

RoR:测试使用http令牌身份验证的操作

  •  20
  • JoseMarmolejos  · 技术社区  · 12 年前

    我正在尝试测试一个在before过滤器中使用http令牌身份验证的控制器。我的问题是,当我使用curl传递令牌时,它可以正常工作,但在我的测试中,它总是失败(我使用的是rspec-btw)。尝试了一个简单的测试来查看令牌是否被传递,但似乎没有这样做。我是否错过了让测试真正将令牌传递给控制器的任何东西?

    这是我的前置过滤器:

        def restrict_access
          authenticate_or_request_with_http_token do |token, options|
            api_key = ApiKey.find_by_access_token(token)
            @user = api_key.user unless api_key.nil?
            @token = token #set just for the sake of testing
            !api_key.nil?
          end 
        end
    

    这是我的测试:

        it "passes the token" do
          get :new, nil,
            :authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
    
          assigns(:token).should be "test_access1"
        end
    
    1 回复  |  直到 12 年前
        1
  •  29
  •   Serge Balyuk    12 年前

    我假设ApiKey是一个ActiveRecord模型,对吗?curl命令针对开发数据库运行,测试针对测试数据库运行。我在你的片段中看不到任何设置ApiKey的内容。除非你在其他地方有,否则试着按照以下方式添加一些内容:

    it "passes the token" do
      # use factory or just create record with AR:
      ApiKey.create!(:access_token => 'test_access1', ... rest of required attributes ...)
    
      # this part remains unchanged
      get :new, nil,
        :authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
    
      assigns(:token).should be "test_access1"
    end
    

    您可以稍后将其移动到 before :each 块或支撑模块。

    更新:

    看到你的评论后,我不得不深入研究。这是另一个猜测。这种形式的 get

    get '/path', nil, :authorization => 'string'
    

    应该只在集成测试中工作。对于控制器测试,身份验证准备应该如下所示:

    it "passes the token" do
      request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
      get :new
      assigns(:token).should be "test_access1"
    end
    

    这背后的原因来自各个测试模块的方法签名:

    # for action_controller/test_case.rb
    def get(action, parameters = nil, session = nil, flash = nil)
    
    # for action_dispatch/testing/integration.rb
    def get(path, parameters = nil, headers = nil)