如何在 Rails 5 控制器测试中测试或绕过 Basic Auth
How to test or bypass Basic Auth in Rails 5 testing of controllers
我想测试 Rails 5 中激活了基本身份验证的控制器。
current official instruction(截至 2018-10-14)中解释的方式由于某种原因不起作用。
问答“”对于 Rails 5(至少对于默认值而言)似乎太旧了。
这是一个重现案例的简化示例。
我从全新安装的 Rails(最新稳定版 5.2.1):
通过脚手架制作了文章模型和相关资源
bin/rails g scaffold Article title:string content:text
并在控制器中添加了基本的身份验证功能,继official guide之后;那么 ArticlesController 就是这样的,当然可以:
# /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
official instruction说明了测试基本认证的方法;你加
request.headers['Authorization']
在控制器测试文件的 setup
块中,我这样做了:
# /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
失败如下:
# 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
方法 returns 为零,因此 request.headers['Authorization']
失败。如果将语句放在 'testing-index' 块的顶部,则相同。
我发现 request
returns 一个合适的值 在 get articles_url
是 运行 之后,但是为时已晚那时;我的意思是,到那时身份验证已经失败(很明显)。通过一些谷歌搜索,似乎有些人使用 @request
和 @response
来代替,但我也发现它们与 request
完全相同(预期?),即是,它们在 get
.
之前为零
在Rails5中控制器测试或集成测试中绕过或测试Basic Auth的方法是什么?
编辑:
"current official instruction (as of 2018-10-14)" is apparently wrong. See .
测试文档 were incorrect and have been updated but not yet released. The updated docs 阅读:
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') }
我想测试 Rails 5 中激活了基本身份验证的控制器。 current official instruction(截至 2018-10-14)中解释的方式由于某种原因不起作用。 问答“”对于 Rails 5(至少对于默认值而言)似乎太旧了。
这是一个重现案例的简化示例。
我从全新安装的 Rails(最新稳定版 5.2.1):
bin/rails g scaffold Article title:string content:text
并在控制器中添加了基本的身份验证功能,继official guide之后;那么 ArticlesController 就是这样的,当然可以:
# /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
official instruction说明了测试基本认证的方法;你加
request.headers['Authorization']
在控制器测试文件的 setup
块中,我这样做了:
# /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
失败如下:
# 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
方法 returns 为零,因此 request.headers['Authorization']
失败。如果将语句放在 'testing-index' 块的顶部,则相同。
我发现 request
returns 一个合适的值 在 get articles_url
是 运行 之后,但是为时已晚那时;我的意思是,到那时身份验证已经失败(很明显)。通过一些谷歌搜索,似乎有些人使用 @request
和 @response
来代替,但我也发现它们与 request
完全相同(预期?),即是,它们在 get
.
在Rails5中控制器测试或集成测试中绕过或测试Basic Auth的方法是什么?
编辑:
"current official instruction (as of 2018-10-14)" is apparently wrong. See
测试文档 were incorrect and have been updated but not yet released. The updated docs 阅读:
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') }