简体   繁体   中英

RSpec error ActionController::UrlGenerationError: when testing controller

I am writing the specs (with RSpec) for my API controller. When I test the GET request for the index everything works well, it returns the expected body and successful response, however, when I test the GET request for the show action it raises the following error:

ActionController::UrlGenerationError:
   No route matches {:action=>"show", :controller=>"api/v1/contacts"}

Here is the code that I have written in my spec file:

 require 'rails_helper' RSpec.describe Api::V1::ContactsController do describe "GET #index" do context 'with a successful request' do before do get :index end it "returns http success" do expect(response).to have_http_status(:success) expect(response.status).to eq(200) end it "JSON body response contains expected recipe attributes" do json_response = JSON.parse(response.body) expect(json_response.keys).to match_array(%w[data included]) end end end describe "GET #show" do context 'with a successful request' do before do get :show end it "returns http success" do expect(response).to have_http_status(:success) expect(response.status).to eq(200) end end end end

Here is the show route that the command rails routes prints 在此处输入图片说明

Can someone help me see what am I missing? How can I test the GET request for the show action with RSpec?

The error is caused by the fact that you are not passing the slug parameter required by your route:

get :show, slug: contact.slug

But what you actually want here in the first place is a request spec and not a controller spec. A request spec sends actual HTTP requests to your application. Controller specs mock out most of the framework and let the bugs march right though - especially routing bugs.

The use of controller specs is discouraged by the the Rails and RSpec teams and should not be used outside of legacy code.

# spec/requests/api/v1/contacts_spec.rb
require 'rails_helper'

RSpec.describe 'API V1 Contacts', type: :request do

  # This can be DRY:ed into a shared context
  let(:json){ JSON.parse(response.body) }
  subject { response }
  
  # This example uses FactoryBot
  # https://github.com/thoughtbot/factory_bot
  let(:contact) { FactoryBot.create(:contact) }

  # but you could also use a fixture
  let(:contact){ contacts[:one] }
  
  # describe the actual API and not how its implemented
  describe "GET '/api/v1/contacts'" do
    before { get api_vi_contacts_path }
    it { is_expected.to be_successful }
    it "has the correct response attributes" do
      expect(json.keys).to match_array(%w[data included])
    end
  end
  
  describe "GET '/api/v1/contacts/:id'" do
    before { get api_vi_contact_path(contact) }
    it { is_expected.to be_successful }
    # @todo write examples about the JSON
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM