ruby-on-railsrspecrspec-rails

Issue with Rspec testing form views with scoped route


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?


Solution

  • 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