如何使用 rspec 在控制器中测试自定义路由
How to test custom routes in controller with rspec
我在中定义了一个自定义路由
routes.rb
get "packages/city/:location_id", to: "packages#index"
在controller_spec.rb
、
get :index
给出这个错误,
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"packages"}
如何在控制器规范中明确指定自定义路由?
如果您这样声明您的路线,也许会有帮助?
get "packages/city/:location_id" => "packages#index"
记得在规范中提供 location_id
参数,例如get :index, location_id: 1
.
因为你没有通过location_id
路由定义为匹配:
/packages/city/:location_id
所以为了遵守它,你需要做类似
的事情
get :index, location_id: 1234
控制器规格有同样的问题:
# rake routes | grep media_order
teacher_work_media_orders PATCH /teacher/works/:work_id/media_orders(.:format) teacher/media_orders#update
当我这样做的时候:
# spec/controller/teacher/media_orders_controller
patch :update data: {}
我得到了
Failure/Error: patch :update
ActionController::UrlGenerationError:
No route matches {:action=>"update", :controller=>"teacher/media_orders"}
但当我这样做时
patch :update, work_id: 1234, data: {}
有效
2017
我尝试了上面的解决方案,但它们没有用。我得到了:
ArgumentError:
unknown keyword: location_id
似乎 RSpec 现在需要一个 params
参数。相应的调用如下所示:
get(:index, params: { location_id: 123 })
2019
正在解决我的控制器规格中的同样错误。尝试接受并跟进解决方案,但它们也没有用,要么导致无方法错误,要么持续出现无路由匹配错误。
像接受的解决方案那样直接定义路由也不满足错误。
经过多次搜索和一些键盘粉碎测试通过。
注意事项
- 控制器用于多态资源
- 路由嵌套在
resources :location, only[:index, :show] do ... end
中
- 这是 API 条路线,所以 JSON 只有
解决方案
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
所以最后它是两种解决方案的组合,但必须将它们放在 params hash 中否则它会抛出 name/no 方法或路由错误
结论
- 对关联的引用必须在参数哈希中
- 即使控制器responds_to:json,它也会抛出错误,没有路由错误
- 必须在您的请求中包含数据哈希,否则不会出现路由匹配错误
希望这对您有所帮助,
干杯!
我在中定义了一个自定义路由 routes.rb
get "packages/city/:location_id", to: "packages#index"
在controller_spec.rb
、
get :index
给出这个错误,
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"packages"}
如何在控制器规范中明确指定自定义路由?
如果您这样声明您的路线,也许会有帮助?
get "packages/city/:location_id" => "packages#index"
记得在规范中提供 location_id
参数,例如get :index, location_id: 1
.
因为你没有通过location_id
路由定义为匹配:
/packages/city/:location_id
所以为了遵守它,你需要做类似
的事情
get :index, location_id: 1234
控制器规格有同样的问题:
# rake routes | grep media_order
teacher_work_media_orders PATCH /teacher/works/:work_id/media_orders(.:format) teacher/media_orders#update
当我这样做的时候:
# spec/controller/teacher/media_orders_controller
patch :update data: {}
我得到了
Failure/Error: patch :update
ActionController::UrlGenerationError:
No route matches {:action=>"update", :controller=>"teacher/media_orders"}
但当我这样做时
patch :update, work_id: 1234, data: {}
有效
2017
我尝试了上面的解决方案,但它们没有用。我得到了:
ArgumentError:
unknown keyword: location_id
似乎 RSpec 现在需要一个 params
参数。相应的调用如下所示:
get(:index, params: { location_id: 123 })
2019
正在解决我的控制器规格中的同样错误。尝试接受并跟进解决方案,但它们也没有用,要么导致无方法错误,要么持续出现无路由匹配错误。
像接受的解决方案那样直接定义路由也不满足错误。
经过多次搜索和一些键盘粉碎测试通过。
注意事项
- 控制器用于多态资源
- 路由嵌套在
resources :location, only[:index, :show] do ... end
中
- 这是 API 条路线,所以 JSON 只有
解决方案
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
所以最后它是两种解决方案的组合,但必须将它们放在 params hash 中否则它会抛出 name/no 方法或路由错误
结论
- 对关联的引用必须在参数哈希中
- 即使控制器responds_to:json,它也会抛出错误,没有路由错误
- 必须在您的请求中包含数据哈希,否则不会出现路由匹配错误
希望这对您有所帮助,
干杯!