Search code examples
ruby-on-railsrspecrspec-rails

Rspec request specs: No routes match


Writing request specs for rail app (api-only) and running into an issue where request spec returns:

Failures:

  1) Api::V1::BooksController sends a list of books
     Failure/Error: get api_books_path
     
     ActionController::RoutingError:
       No route matches [GET] "/books"

At first, I though maybe test couldn't infer the directory path so I made sure that config.infer_spec_type_from_file_location! was in spec/rails_helper

directory structure of spec directory:

spec/requests
└── api
    └── v1
        └── books_spec.rb

contents of spec/requests/api/v1/books_spec.rb:

require 'rails_helper'

RSpec.describe Api::V1::BooksController, :type => :request  do

  before { host! "api.localhost.com" }

  it "sends a list of books" do

    get api_books_path

    expect(response).to be_successful
  end
end

directory structure of app/controllers:

app/controllers
├── api
│   └── v1
│       └── books_controller.rb
├── application_controller.rb
└── concerns

Contents of config/routes.rb:

require 'api_versions'

Rails.application.routes.draw do

  namespace :api, defaults: {format: :json}, constraints: { subdomain: ['api', 'staging.api'] }, path: "/" do
    scope module: :v1, constraints: ApiVersions.new(version: 1, default: true) do
      resources :books, only: [:index]
    end
  end
end

I can't seem to figure out what I am missing; appreciate any feedback.


Solution

  • A good night sleep really does help. I woke up; took another look at the problem and realized the culprit.

    • Main issue was that in spec/requests/api/v1/books_spec.rb host was set to api.localhost.com (localhost.com; really?) when it should be api.localhost:3000.
    • Second issue was forgetting to set the correct value for config.action_dispatch.tld_length in test; I did in dev but forgot to do so in test.