Rspec Rails 4.2.5使用基本的http auth请求测试通过

时间:2016-01-22 11:53:50

标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails

设置如下。对于每个http请求,管理器在标头(name,pw)中发送其凭证。这些将根据数据库中的条目进行检查,如果成功则返回所需的用户对象。如何在请求测试中实现基本的http_auth?我想只添加密码和用户名并测试返回值?请求测试的目标是哪个,对吧?我尝试了以下但没有取得多大成功:

我在spec/support/auth_helper.rb中使用

创建了一个AuthHelper模块
module AuthHelper
  def http_login
    user = 'test'
    pw = 'test'
    request.ENV['HTTP_AUTHORIZATION'] =ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
   end  
end

并在requests/api/user_spec.rb中使用它,如下所示

include AuthHelper
 describe "User API get 1 user object" do     
      before(:each) do
               http_login 
       end

但是我收到此错误消息。我该如何解决这个问题并使我的测试能够通过http_auth?我也在这里阅读了很多类似的topis和问题 它们主要适用于旧版本的rspec和rails,并不适用于我的案例

提前致谢!

Failure/Error: request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

 NoMethodError:
   undefined method `env' for nil:NilClass# ./spec/support

 # ./spec/support/auth_helper.rb:5:in `http_login'
 # ./spec/requests/api/user_spec.rb:8:in `block (2 levels) in <top (required)>'

更新

我在请求中移动了标题生成。我查了一下Auth动词,所以我觉得作业应该有效。我在rails控制台中测试了ActionController调用并收到了一个字符串。我想这也是正确的。我的整个测试现在看起来像这样:

describe "User API get 1 user object", type: :request do  
      it 'Get sends back one User object ' do             
              headers = {   
                            "AUTHORIZATION" =>ActionController::HttpAuthentication::Basic.encode_credentials("test","test")
   #                        "AUTHORIZATION" =>ActionController::HttpAuthentication::Token.encode_credentials("test","test")
              }
              FactoryGirl.create(:user)
              get "/api/1/user", headers
              #json = JSON.parse(response.body)
              expect(response).to be_success
      #       expect(response.content_type).to eq("application/json")
      end     
  end     

收到以下错误:

会使行@buf=["HTTP Basic: Access denied.\n"]变得粗糙,因此仍然会拒绝访问。

Failure/Error: expect(response).to be_success
   expected `#<ActionDispatch::TestResponse:0x000000070d1d38 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x000000070d1c98>, @stream=#<ActionDispatch::Response::Buffer:0x000000070d1c48 @response=#<ActionDispatch::TestResponse:0x000000070d1d38 ...>, 
 @buf=["HTTP Basic: Access denied.\n"], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "WWW-Authenticate"=>"Basic realm=\"Application\"", "Content-Type"=>"text/html; charset=utf-8", "Cache-Control"=>"no-cache", "X-Request-Id"=>"9c27d4e9-84c0-4ef3-82ed-cccfb19876a0", "X-Runtime"=>"0.134230", "Content-Length"=>"27"}, @status=401, @sending_file=false, @blank=false, 
@cv=#<MonitorMixin::ConditionVariable:0x000000070d1bf8 @monitor=#<ActionDispatch::TestResponse:0x000000070d1d38 ...>, @cond=#<Thread::ConditionVariable:0x000000070d1bd0>>, @committed=false, @sending=false, @sent=false, @content_type=#<Mime::Type:0x00000002af78f8 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, @charset="utf-8", @cache_control={:no_cache=>true}, @etag=nil>.success?` 
to return true, got false

这个测试尚未完善(但是),但至少现在已经过去了。

describe "User API get 1 user object", type: :request do  
    it 'Get sends back one User object ' do             
        @env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
              FactoryGirl.create(:user)

        get "/api/1/user", {}, @env

        JSON.parse(response.body)
        expect(response).to be_success
        expect(response.status).to eq 200
    end     
end     

2 个答案:

答案 0 :(得分:1)

请仔细阅读错误:undefined method `env' for nil:NilClass表示request为零。您是否在 测试中定义请求时尝试在测试之前设置标题

您可能需要查看有关如何设置标题的文档for an example

如果您仍然卡住了,也请发布一个测试。

答案 1 :(得分:0)

这一行看起来很可疑:

request.ENV['HTTP_AUTHORIZATION'] =ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

您确定"ENV"应该大写吗?我认为应该写成"env"