RSpec error ActionController::UrlGenerationError: when testing controller
RSpec error ActionController::UrlGenerationError: when testing controller
我正在为我的 API 控制器编写规范(使用 RSpec)。当我测试索引的 GET 请求时,一切正常,它 returns 预期的主体和成功的响应,但是,当我测试 show 操作的 GET 请求时,它会引发以下错误:
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"api/v1/contacts"}
这是我在规范文件中编写的代码:
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
这是命令 rails routes
打印的显示路由
谁能帮我看看我错过了什么?
如何使用 RSpec 测试 show 操作的 GET 请求?
错误是由于您没有传递路由所需的slug参数造成的:
get :show, slug: contact.slug
但您首先真正想要的是 request spec 而不是控制器规格。请求规范将实际的 HTTP 请求发送到您的应用程序。控制器规范模拟了大部分框架并让错误继续前进 - 特别是路由错误。
Rails 和 RSpec 团队不鼓励使用控制器规范,不应在遗留代码之外使用。
# 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
我正在为我的 API 控制器编写规范(使用 RSpec)。当我测试索引的 GET 请求时,一切正常,它 returns 预期的主体和成功的响应,但是,当我测试 show 操作的 GET 请求时,它会引发以下错误:
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"api/v1/contacts"}
这是我在规范文件中编写的代码:
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
这是命令 rails routes
打印的显示路由
谁能帮我看看我错过了什么? 如何使用 RSpec 测试 show 操作的 GET 请求?
错误是由于您没有传递路由所需的slug参数造成的:
get :show, slug: contact.slug
但您首先真正想要的是 request spec 而不是控制器规格。请求规范将实际的 HTTP 请求发送到您的应用程序。控制器规范模拟了大部分框架并让错误继续前进 - 特别是路由错误。
Rails 和 RSpec 团队不鼓励使用控制器规范,不应在遗留代码之外使用。
# 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