Search code examples
ruby-on-railstestingroutesrspec-rails

In rspec file, I am getting => Error: ActionController::RoutingError: No route matches xxxxxxx despite valid routing


I am very very new to testing and new to rails (less than 1 year of experience). Please keep this in view before answering.

I have a model recipe which belongs to a source and source belongs to client.

Route is:

client_source_recipes GET /clients/:client_id/sources/:source_id/recipes(.:format) recipes#index

I am trying to test this:

RSpec.describe RecipesController, :type => :controller do

# Prerequisites go here (mentioned at the end of the question)

  describe "GET #index" do
    it "assigns all recipes as @recipes" do
      recipe = Recipe.create! valid_attributes
      get :index, params: { client_id: client.id, source_id: source.id, locale: 'cs' }, session: valid_session
      expect(assigns(:recipes)).to eq([recipe])

      # Commented below are different ways I tried but failed:

      # visit client_source_recipes_path(client.id, source.id, locale: 'cs')
      # visit "/client/#{client.id}/source/#{source.id}/recipes?locale=cs"
      # get client_source_recipes_path, params: { client_id: client.id, source_id: source.id, locale: 'cs' }, session: valid_session
      # get client_source_recipes_path(client.id, source.id, locale: 'cs')
    end
  end
end

Prerequisites for test:

  login_user         # defined - works well

  let(:client) { create :client }                                         # defined in factories 
  let(:source) { create :source, warehouse_id: 1, client_id: client.id }  # defined in factories

  let(:valid_attributes) {
    { name: "name", source_id: source.id }
  }

  let(:valid_session) { {"warden.user.user.key" => session["warden.user.user.key"]} }   # works well in other tests

Why do I get the error of route when same route is being used everywhere else?

Errors:

 Error: ActionController::RoutingError: No route matches {:controller=>"recipes", :params=>{:client_id=>"1", :source_id=>"1", :locale=>"cs"}, :session=>{"warden.user.user.key"=>[["1"], "$2a$04$bobnhLAlKEsxZtlJheY64."]}}

 Error: ActionController::RoutingError: No route matches {:controller=>"recipes", :action=>"/clients/1/sources/1/recipes?locale=cs"}

 Error: ActionController::RoutingError: No route matches {:controller=>"recipes", :action=>"/clients/1/sources/1/recipes"}

# etc. etc. i.e. errors are more or less the same

Thanks in advance.


Solution

  • OK!

    I have 'spent' like 5 hours pondering on this but could not do it in any way and now I found out that the only issue was syntax:

    Wrong (old) syntax (expects params and session as arguments explicitly):

    get :index, { client_id: client.id, source_id: source.id, locale: 'cs' }, session: valid_session
    
    #or
    
    get :index, params: { client_id: client.id, source_id: source.id, locale: 'cs' }, session: valid_session
    

    Right (newer) syntax (accepts params and session as arguments implicitly):

    get :index, { client_id: client.id, source_id: source.id, locale: 'cs' }, valid_session
    

    I hope it saves precious time of other people, unlike me ):