如何使用 minitest 和 Rails 访问请求的 headers?

how to access request's headers using minitest with Rails?

我有如下测试环境配置

ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require 'minitest/rails'

# Consider setting MT_NO_EXPECTATIONS to not add expectations to Object.
# ENV["MT_NO_EXPECTATIONS"] = true

Dir[Rails.root.join('test/support/**/*.rb')].each { |f| require f }

class ActiveSupport::TestCase
  # Run tests in parallel with specified workers
  # parallelize(workers: :number_of_processors)

  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

和下面的测试

describe Abi::OrganizationsController do
  before do
    @request.headers['x-abi-token'] = 'test'
  end

  describe '#create' do
    let(:credit_rating) { 'A' }
    let(:organization_data) do
      {
        organization: {
          name: 'Test Organization',
          ....
    end

    it 'should return an organization id' do
      post(abi_organizations_path, params: organization_data)
    end
  end
end

在需要发送新的 header 之前,测试运行得非常好。

我尝试使用 @request.headers,但此时 @requestnil,但我尝试的任何方法都没有帮助。

当我将 class 更新为这个

时,我设法获得了 @request
class Abi::OrganizationsControllerTest < ActionController::TestCase

但是,我不得不将主题更改为:

post :create, params: organization_data # <-- new subject
# post(abi_organizations_path, params: organization_data)

这是我不想做的事情,然后我开始看到这个错误

RuntimeError Exception: @controller is nil: make sure you set it in your test's setup method.

我有点迷路了,我在互联网上找不到任何有用的东西,我觉得我是唯一遇到这个问题的人,这没有任何意义。

有人试过这个吗?

这是来自 Rails 中的完整性检查。

https://github.com/rails/rails/blob/18707ab17fa492eb25ad2e8f9818a320dc20b823/actionpack/lib/action_controller/test_case.rb#L629-L637

我最好的选择是您的测试 class 名称与任何控制器名称都不匹配。您的测试 class 称为 Abi::OrganizationsControllerTest,因此 Rails 将假定控制器 class 类似于 Abi::OrganizationsController.

https://github.com/rails/rails/blob/18707ab17fa492eb25ad2e8f9818a320dc20b823/activesupport/lib/active_support/testing/constant_lookup.rb#L36