RSpec测试控制器动作回调:解决匿名控制器报错与请求头传参问题
问题解决方案
1. 修复undefined method 'controller'报错
这个报错由两个常见问题导致:
- 匿名控制器写法错误:rspec-rails提供的
controller匿名控制器DSL,在测试ApiApplicationController这类基类控制器时,不需要传入父类参数——只要你在RSpec.describe ApiApplicationController的测试块内调用无参的controller,RSpec会自动生成继承自该基类的匿名子控制器,手动传参反而会触发方法找不到的异常。 - 缺少控制器测试类型标记:如果你的测试文件没有存放在
spec/controllers/目录下,或者没有开启RSpec的自动类型推断功能,需要手动给describe块添加type: :controller标记,才会加载控制器测试专属的DSL方法。
2. 传入自定义请求头
Rails 5及以上版本的控制器测试中,get/post等请求方法的第三个参数为headers哈希,直接将自定义头键值对传入即可。你之前写的let('INFO')只是定义了测试内部变量,不会自动注入到请求头中,需要手动传递。
修正后的可用测试代码
require 'rails_helper' # 非spec/controllers路径下的文件必须加type: :controller标记 RSpec.describe ApiApplicationController, type: :controller do # 无参调用,自动生成继承ApiApplicationController的匿名控制器 controller do def index # 增加简单返回,避免模板缺失报错 render plain: 'success' end end let(:test_info_value) { "some information" } it '子控制器任意动作执行前,会自动读取请求头INFO写入InformationSet' do # 传入自定义header get :index, params: {}, headers: { 'INFO' => test_info_value } expect(InformationSet.last.info).to eq(test_info_value) end end
兼容说明
- 如果你使用Rails 4及更早版本,传header的写法需要调整:在发起请求前先执行
request.headers['INFO'] = test_info_value,再调用get :index即可。 - 匿名控制器内的测试动作必须添加明确的返回(比如render plain、render json),否则会触发模板找不到的错误,影响测试判断。
内容的提问来源于stack exchange,提问作者Senonik
相关产品推荐
相关产品推荐

