简体   繁体   English

如何使用rspec在控制器中测试自定义路由

[英]How to test custom routes in controller with rspec

I have defined a custom route in routes.rb 我在routes.rb中定义了一个自定义路由

get "packages/city/:location_id",  to: "packages#index"

In controller_spec.rb , controller_spec.rb

get :index

gives this error, 给出了这个错误,

ActionController::UrlGenerationError:
   No route matches {:action=>"index", :controller=>"packages"}

How to explicitly specify the custom routes in controller specs? 如何在控制器规范中明确指定自定义路由?

Perhaps it helps if you declare your route like this? 如果您宣布这样的路线,也许会有所帮助?

get "packages/city/:location_id" => "packages#index"

Remember to provide a location_id param in specs, eg get :index, location_id: 1 . 请记住在规范中提供location_id参数,例如get :index, location_id: 1

2017 2017年

I tried the solutions above but they did not work. 我尝试了上面的解决方案,但他们没有工作。 I got: 我有:

ArgumentError:
   unknown keyword: location_id

It seems that RSpec now requires a params parameter. 似乎RSpec现在需要一个params参数。 The corresponding call would look like this: 相应的调用如下所示:

get(:index, params: { location_id: 123 })

it's because you are not passing location_id 这是因为你没有传递location_id

the route is defined to match: 路线定义为匹配:

/packages/city/:location_id

so in order to comply with it you need to do something like 所以为了遵守它,你需要做类似的事情

get :index, location_id: 1234

Had the same issue with Controller spec: 与Controller规范有相同的问题:

# rake routes | grep media_order
teacher_work_media_orders PATCH /teacher/works/:work_id/media_orders(.:format)  teacher/media_orders#update

when I did: 当我做的时候:

# spec/controller/teacher/media_orders_controller
patch :update data: {}

I got 我有

 Failure/Error: patch :update
 ActionController::UrlGenerationError:
   No route matches {:action=>"update", :controller=>"teacher/media_orders"}

but when I did 但是当我这样做的时候

patch :update, work_id: 1234, data: {}

that worked 有效

2019 2019

Was tackling this same error on my controller specs. 在我的控制器规格上解决了同样的错误。 Tried accepted and follow up solutions, but they also did not work, either led to no method error or persisted the no route match error. 尝试接受和跟进解决方案,但他们也没有工作,或导致没有方法错误或持续无路由匹配错误。

Directly defining the route like in the accepted solution also did not satisfy the errors. 直接定义路径就像在接受的解决方案中一样也不能满足错误。

After much searching and some keyboard smashing tests pass. 经过多次搜索和一些键盘粉碎测试通过。

Things to note 注意事项

  • controller is for polymorphic resource controller用于多态资源
  • routes are nested within the resources :location, only[:index, :show] do ... end 路由嵌套在resources :location, only[:index, :show] do ... end
  • this is API routes, so JSON only 这是API路由,所以只有JSON

Solution

let(:location) do
    create(:location)
  end


shared_examples("a user who can't manage locations") do
    describe 'GET #index' do
      it 'denies access' do

        get :index, params:{location_id: location.locationable.id, format: :json}
        expect(response).to have_http_status :unauthorized
      end
    end
end

So in the end it was a combination of both solutions, but had to put them in the params hash or else it would throw name/no method or route errors 所以最后它是两个解决方案的组合,但不得不将它们放在params散列中,否则它会抛出名称/没有方法或路由错误

Conclusion 结论

  • references to the association must be in the params hash 对关联的引用必须在params哈希中
  • even if controller responds_to :json, it will throw errors no route errors 即使控制器响应_s:json,它也会抛出错误,没有路由错误
  • must include a data hash in your request or no route match errors will appear 必须在请求中包含数据哈希,否则不会出现路由匹配错误

Hope this helps, 希望这可以帮助,

Cheers! 干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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