如何在Rails RSpec视图测试中正确传递参数?
解决Rails视图测试中路由参数缺失的问题
问题根源
视图里的edit_job_path(params[:job_id])依赖请求参数job_id,但测试渲染视图时未传入该参数,导致params[:job_id]为nil,触发路由缺失必填key的错误。
正确解决方案
方案1:渲染视图时传入请求参数
在测试的render方法中通过params选项明确传递job_id,如果项目中有Job模型,建议用FactoryBot创建真实的Job对象保证数据合理性:
require 'rails_helper' RSpec.describe "interests/show", type: :view do let(:job) { FactoryBot.create(:job) } let(:interest) { FactoryBot.create(:interest) } before(:each) do assign(:interest, interest) end it "renders attributes in <td>" do # 通过params选项传递job_id参数 render template: "interests/show", params: { job_id: job.id } expect(rendered).to match(/interest 1/) end end
方案2:优化视图代码,从关联对象获取参数(更推荐)
如果Interest和Job是关联关系(比如Interest belongs_to :job),视图不要直接依赖请求参数,而是从@interest的关联对象中获取job id,这样更符合Rails关联设计,也能避免参数依赖问题:
修改视图app/views/interests/show.html.slim:
- content_for :page_title do h2 View enquiry = render "interests/interest", interest: @interest # 从关联对象获取job id,替代params[:job_id] = link_to "Back", edit_job_path(@interest.job.id)
对应的测试代码只需保证Interest关联了Job:
require 'rails_helper' RSpec.describe "interests/show", type: :view do let(:job) { FactoryBot.create(:job) } # 创建关联了job的interest let(:interest) { FactoryBot.create(:interest, job: job) } before(:each) do assign(:interest, interest) end it "renders attributes in <td>" do render template: "interests/show" expect(rendered).to match(/interest 1/) end end
为什么之前的方案无效?
assign是设置视图的实例变量(如@interest),但不会修改请求层面的params对象,所以用assign传参不生效。- 之前的render传参如果没有用
params:选项,只是传递了局部变量,而视图里用的是params[:job_id],两者不是同一个对象,所以也无效。
内容的提问来源于stack exchange,提问作者rinold simon
相关产品推荐
相关产品推荐

