Why am I getting ActionController::UrlGenerationError: "No route matches" in my controller spec?
Why am I getting ActionController::UrlGenerationError: "No route matches" in my controller spec?
我的控制器规格如下所示:
# config_controller_spec.rb
require "spec_helper"
describe Api::V4::ConfigController, type: :controller do
let(:parsed_response) { response.body.to_json }
describe 'GET app_config' do
it "renders successfully" do
get :app_config
expect(response).to be_success
expect(parsed_response).to eq("{key: val}")
end
end
end
当我 运行 但是,我得到:
ActionController::UrlGenerationError:
No route matches {:action=>"app_config", :controller=>"api/v4/config"}
我不明白为什么。我在谷歌上搜索了一下,发现如果我像这样在 get 调用中添加:use_route: :config
:get :app_config, use_route: :config
,那么它会出于某种原因起作用,尽管我不明白为什么?但是在附加它时,我收到以下弃用错误:
DEPRECATION WARNING: Passing the `use_route` option in functional tests are deprecated. Support for this option in the `process` method (and the related `get`, `head`, `post`, `patch`, `put` and `delete` helpers) will be removed in the next version without replacement.
Functional tests are essentially unit tests for controllers and they should not require knowledge to how the application's routes are configured. Instead, you should explicitly pass the appropiate params to the `process` method.
Previously the engines guide also contained an incorrect example that recommended using this option to test an engine's controllers within the dummy application.
That recommendation was incorrect and has since been corrected.
Instead, you should override the `@routes` variable in the test case with `Foo::Engine.routes`. See the updated engines guide for details.
这是我的控制器:
# config_controller.rb
class Api::V4::ConfigController < Api::V4::BaseController
def app_config
render json: Api::V6::Config.app_config, root: false
end
end
和路线:
# routes.rb
MyApp::Application.routes.draw do
constraints subdomain: /\Awww\b/ do
namespace :api, defaults: {format: 'json'} do
get 'app_config' => 'config#app_config'
end
end
end
使用请求规范而不是控制器规范:
describe "Api V4 Configuration", type: :request do
let(:json) { JSON.parse(response.body) }
subject { response }
describe 'GET app_config' do
before { get "/api/v4/app_config" }
it { should be_successful }
it "has the correct contents" do
expect(json).to include(foo: "bar")
end
end
end
Rails 5 的最大变化之一是 ActionController::TestCase
(RSpec 控制器规格包装)的贬值以支持集成测试。因此,使用 request specs 是一种更具前瞻性的解决方案 - 使用较少的抽象也意味着您的规范也将正确地涵盖路由。
此外,您似乎没有正确嵌套路线:
# routes.rb
MyApp::Application.routes.draw do
constraints subdomain: /\Awww\b/ do
namespace :api, defaults: {format: 'json'} do
namespace :v4 do
get 'app_config' => 'config#app_config'
end
end
end
end
参见:
我的控制器规格如下所示:
# config_controller_spec.rb
require "spec_helper"
describe Api::V4::ConfigController, type: :controller do
let(:parsed_response) { response.body.to_json }
describe 'GET app_config' do
it "renders successfully" do
get :app_config
expect(response).to be_success
expect(parsed_response).to eq("{key: val}")
end
end
end
当我 运行 但是,我得到:
ActionController::UrlGenerationError:
No route matches {:action=>"app_config", :controller=>"api/v4/config"}
我不明白为什么。我在谷歌上搜索了一下,发现如果我像这样在 get 调用中添加:use_route: :config
:get :app_config, use_route: :config
,那么它会出于某种原因起作用,尽管我不明白为什么?但是在附加它时,我收到以下弃用错误:
DEPRECATION WARNING: Passing the `use_route` option in functional tests are deprecated. Support for this option in the `process` method (and the related `get`, `head`, `post`, `patch`, `put` and `delete` helpers) will be removed in the next version without replacement.
Functional tests are essentially unit tests for controllers and they should not require knowledge to how the application's routes are configured. Instead, you should explicitly pass the appropiate params to the `process` method.
Previously the engines guide also contained an incorrect example that recommended using this option to test an engine's controllers within the dummy application.
That recommendation was incorrect and has since been corrected.
Instead, you should override the `@routes` variable in the test case with `Foo::Engine.routes`. See the updated engines guide for details.
这是我的控制器:
# config_controller.rb
class Api::V4::ConfigController < Api::V4::BaseController
def app_config
render json: Api::V6::Config.app_config, root: false
end
end
和路线:
# routes.rb
MyApp::Application.routes.draw do
constraints subdomain: /\Awww\b/ do
namespace :api, defaults: {format: 'json'} do
get 'app_config' => 'config#app_config'
end
end
end
使用请求规范而不是控制器规范:
describe "Api V4 Configuration", type: :request do
let(:json) { JSON.parse(response.body) }
subject { response }
describe 'GET app_config' do
before { get "/api/v4/app_config" }
it { should be_successful }
it "has the correct contents" do
expect(json).to include(foo: "bar")
end
end
end
Rails 5 的最大变化之一是 ActionController::TestCase
(RSpec 控制器规格包装)的贬值以支持集成测试。因此,使用 request specs 是一种更具前瞻性的解决方案 - 使用较少的抽象也意味着您的规范也将正确地涵盖路由。
此外,您似乎没有正确嵌套路线:
# routes.rb
MyApp::Application.routes.draw do
constraints subdomain: /\Awww\b/ do
namespace :api, defaults: {format: 'json'} do
namespace :v4 do
get 'app_config' => 'config#app_config'
end
end
end
end
参见: