How to test or bypass Basic Auth in Rails 5 testing of controllers

谁说胖子不能爱 提交于 2019-12-13 14:12:47

问题


I would like to test controllers in Rails 5 for which Basic Authentication is activated. The way explained in the current official instruction (as of 2018-10-14) does not work for some reason. The Q&A "Testing HTTP Basic Auth in Rails 2.2+" seems too old for Rails 5 (at least for the default).

Here is a simplified example to reproduce the case.
I made an Article model and related resources by scaffold from a fresh install of Rails (latest stable version 5.2.1):

bin/rails g scaffold Article title:string content:text

and added the basic auth function to the controller, following the official guide; then the ArticlesController is like this, which certainly works:

# /app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  http_basic_authenticate_with name: "user1", password: "pass"
  before_action :set_article, only: [:show, :edit, :update, :destroy]

  def index
    @articles = Article.all
  end
end

The official instruction explains the way to test basic authentication; you add request.headers['Authorization'] in the setup block in the test file of the controller, which I did:

# /test/controllers/articles_controller_test.rb
require 'test_helper'

class ArticlesControllerTest < ActionDispatch::IntegrationTest
  setup do
    request.headers['Authorization'] =
      ActionController::HttpAuthentication::Basic.encode_credentials("user1", "pass")
    @article = articles(:one)
  end

  test "should get index" do
    get articles_url
    assert_response :success
  end
end

However, bin/rails test fails as follows:

# Running:

E

Error:
ArticlesControllerTest#test_should_get_index:
NoMethodError: undefined method `headers' for nil:NilClass
    test/controllers/articles_controller_test.rb:5:in `block in <class:ArticlesControllerTest>'

bin/rails test test/controllers/articles_controller_test.rb:10

Clearly, request method returns nil, and hence request.headers['Authorization'] fails. It is the same if the statement is placed at the top of 'testing-index' block instead.

I have found request returns a proper value after get articles_url is run, but it is too late by that time; I mean, Authentication has already failed by that time (obviously). With some googling, it seems some people use @request and @response for the purpose instead, but I have also found the they are exactly in the same situation as request (expectedly?), that is, they are nil before get.

What is the way to bypass or test Basic Auth in testing of controllers or integration tests in Rails 5?

EDIT:
"The current official instruction (as of 2018-10-14)" is apparently wrong. See the answer.


回答1:


The testing docs were incorrect and have been updated but not yet released. The updated docs read:

NOTE: If you followed the steps in the Basic Authentication section, you'll need to add authorization to every request header to get all the tests passing:

post articles_url, params: { article: { body: 'Rails is awesome!', title: 'Hello Rails' } }, headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials('dhh', 'secret') }



来源:https://stackoverflow.com/questions/52803228/how-to-test-or-bypass-basic-auth-in-rails-5-testing-of-controllers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!