After scaffolding a new model for our Ruby on Rails application (Rails version 6.0.6), I got several scaffolded Rspec tests for the new views (index, show, new, and edit) for the new model. I double checked that all these views function without issue when the application is running, but after adding updating the Rspec tests (mostly to just add in using FactoryBot), I was only able to get the show and index page tests work. Both the new and edit page tests are failing with a routing issue.
We have the routes for the new model (let's call the model Organization
) defined with a scope:
scope '/:fiscal_year' do
resources :organization, shallow: true
end
I have the updated test for the edit page as:
require 'rails_helper'
RSpec.describe 'organizations/edit' do
let(:organization) { create(:organization) }
before do
assign(:organization, organization)
assign(:fiscal_year, OrganizationFiscalYear::CURRENT_FISCAL_YEAR)
end
it 'renders the edit organization form' do
render
assert_select 'form[action=?][method=?]', organization_path(organization),
'post' do
assert_select 'input[name=?]', 'organization[name]'
end
end
end
And the start of the _form
for the edit and new pages as:
= form_for organization do |f|
...
Unfortunately the spec tests fail at the render
line with the following message:
Failures:
1) organizations/edit renders the edit organization form
Failure/Error: = form_for organization do |f|
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"organizations", :fiscal_year=>#<Organization id: 1, name: "Blah Blah", created_at: "2023-12-22 20:37:45", updated_at: "2023-12-22 20:37:45">}, missing required keys: [:id]
With the stack tracing pointing to line 1 in _form.html.haml
so I can tell it is the form_for
that is generating the error.
I cannot for the life of me figure out why this is producing a routing error. I have triple checked that the views for both edit and new function without any routing errors with the rails server. What am I missing with the spec test?
I finally figured out that the source of my problem is the fact that the views are relying on the current request's parameters to fill in the missing parameters in the URLs that are being generated. I found in the documentation for url_for
the following:
Missing routes keys may be filled in from the current request’s parameters (e.g. :controller, :action, :id and any other parameters that are placed in the path).
In the Rspec view tests these request parameters are not set and so the URL generation is failing. After setting the missing parameters (fiscal_year
for both the new and edit views and id
for the edit view) the spec tests then passed:
before do
assign(:organization, organization)
controller.request.path_parameters[:id] = organization.id
controller.request.path_parameters[:fiscal_year] = OrganizationFiscalYear::CURRENT_FISCAL_YEAR
end