如何在Rails 5控制器测试中测试或绕过Basic Auth [英] How to test or bypass Basic Auth in Rails 5 testing of controllers
问题描述
我想在Rails 5中测试激活了基本身份验证的控制器. 当前的官方说明 a>(截至2018年10月14日)由于某种原因无法正常工作. Q& A"在Rails 2.2+中测试HTTP基本身份验证"对于Rails 5似乎太老了(至少对于默认而言如此).
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).
这是重现案件的简化示例.
我从新安装的Rails(最新的稳定版本5.2.1)中通过脚手架制作了Article模型和相关资源:
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
并遵循官方指南;那么ArticlesController就是这样,它当然可以工作:
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
官方说明解释测试基本身份验证的方法;你添加
我在控制器的测试文件中的setup
块中的request.headers['Authorization']
:
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
但是,bin/rails test
失败,如下所示:
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
很明显,request
方法返回nil,因此request.headers['Authorization']
失败.如果将语句放在"testing-index"块的顶部,则相同.
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.
我发现request
在运行后 返回正确的值get articles_url
,但是到那时已经太迟了;我的意思是,到那时,身份验证已经失败了(很明显).通过一些谷歌搜索,似乎有些人使用@request
和@response
代替,但是我也发现它们与request
处于完全相同的情况(可能是?),也就是说,它们在之前是nil get
.
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
.
在Rails 5的控制器测试或集成测试中,绕过或测试Basic Auth的方法是什么?
What is the way to bypass or test Basic Auth in testing of controllers or integration tests in Rails 5?
" 当前官方指示(截至2018年10月14日)"显然是错误的.参见答案.
"The current official instruction (as of 2018-10-14)" is apparently wrong. See the answer.
推荐答案
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') }
post articles_url, params: { article: { body: 'Rails is awesome!', title: 'Hello Rails' } }, headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials('dhh', 'secret') }
这篇关于如何在Rails 5控制器测试中测试或绕过Basic Auth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!