为什么我得到ActionController :: UrlGenerationError:我的控制器规范中“没有路由匹配”?

时间:2017-04-11 18:58:34

标签: ruby-on-rails rspec rspec-rails

我的控制器规格如下:

# 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"}

我不理解为什么。我用Google搜索并认为如果我将use_route: :config添加到get调用中: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

1 个答案:

答案 0 :(得分:0)

使用请求规范而不是控制器规范:

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

请参阅: