如何在 Rails 5 控制器测试中测试或绕过 Basic Auth

Mas*_*ano 4 ruby testng ruby-on-rails basic-authentication ruby-on-rails-5

我想测试 Rails 5 中激活了基本身份验证的控制器。当前官方说明(截至 2018-10-14)中解释的方式由于某种原因不起作用。问答“在 Rails 2.2+ 中测试 HTTP 基本身份验证”对于 Rails 5 来说似乎太旧了(至少对于默认情况)。

这是重现该案例的简化示例。
我从全新安装的 Rails(最新稳定版 5.2.1)通过脚手架制作了一个文章模型和相关资源:

bin/rails g scaffold Article title:string content:text
Run Code Online (Sandbox Code Playgroud)

并按照官方指南为控制器添加了基本身份验证功能;那么 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
Run Code Online (Sandbox Code Playgroud)

官方指令解释测试基本身份验证的方式; 你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
Run Code Online (Sandbox Code Playgroud)

但是,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
Run Code Online (Sandbox Code Playgroud)

显然,request方法返回 nil,因此request.headers['Authorization']失败。如果将语句放在 'testing-index' 块的顶部,则情况相同。

我发现运行request返回了一个正确的值,但到那时已经太晚了;我的意思是,那时身份验证已经失败(显然)。通过一些谷歌搜索,似乎有些人使用and来代替,但我也发现它们与(预期?)完全相同,也就是说,它们之前为零。 get articles_url@request@responserequestget

在 Rails 5 中的控制器测试或集成测试中,绕过或测试 Basic Auth 的方法是什么?

编辑:
当前的官方说明(截至 2018-10-14)”显然是错误的。见答案

小智 5

测试文档不正确已更新但尚未发布。在最新的文档阅读:

注意:如果您按照基本身份验证部分中的步骤进行操作,则需要为每个请求标头添加授权以使所有测试都通过:

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