ruby-on-rails - RSpec 错误 ActionController::UrlGenerationError: 测试控制器时
问题描述
我正在为我的 API 控制器编写规范(使用 RSpec)。当我测试索引的 GET 请求时一切正常,它返回预期的正文和成功的响应,但是,当我测试 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
有人可以帮我看看我错过了什么吗?如何使用 RSpec 测试 show 操作的 GET 请求?
解决方案
该错误是由于您没有传递路线所需的 slug 参数引起的:
get :show, slug: contact.slug
但是您首先在这里真正想要的是请求规范而不是控制器规范。请求规范将实际的 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
推荐阅读
- puppeteer - 使用 Google Puppeteer 将大文件的 HTML 转换为 PDF
- python - 删除字母或数字前的所有文本
- node.js - 如何将参数从 express 传递给普通的 const 变量?
- scala - Scala:如何在 map/foreach 迭代之间等待?
- javascript - Ember.JS 强制计算属性重新计算
- flutter - 如何在 Flutter 的应用栏下方创建一个带有图标的按钮
- javascript - 在表达式中使用 pow() 或 ^ 时,JS 动画不起作用
- reactjs - 根据服务响应更新 redux 状态
- javascript - firebase.auth().currentUser 始终为空
- node.js - 无法在 VS Code 上执行 Azure Functions