在为 Rails 控制器方法编写测试时,如何将 ID 参数传递给显示方法?
How do I pass an ID parameter to a show method when writing a test for a Rails controller method?
我正在使用 Rails 5. 我的控制器中有以下方法
class LinesController < ApplicationController
...
def show
@line = Line.find(params[:id])
end
使用minitest,我想测试这个方法,所以我把这个写成我的测试...
test "get show page with valid line id" do
test_line_id = 1
get line_url, params: {id: test_line_id}
line = assigns(:line)
assert_equal test_line_id, line.id
assert_response :success
end
但是当我 运行 测试时出现以下错误....
Error:
LinesControllerTest#test_get_show_page_with_valid_line_id:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"lines"} missing required keys: [:id]
test/controllers/lines_controller_test.rb:16:in `block in <class:LinesControllerTest>'
bin/rails test test/controllers/lines_controller_test.rb:14
当我将 ID 作为参数传递时,为什么会出现关于 ID 的错误提示?
编辑:什么抽成路线returns
localhost:myproject davea$ rake routes
Prefix Verb URI Pattern Controller#Action
rails_settings_ui /settings RailsSettingsUi::Engine
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
page GET /pages/:page_name(.:format) pages#show
lines GET /lines(.:format) lines#index
line GET /lines/:id(.:format) lines#show
get_stops GET|POST /lines/:line_id/get_stops(.:format) lines#get_stops
stop GET /stops/:stop_id(.:format) stops#show
search GET /search(.:format) pages#search
favorites GET /favorites(.:format) favorites#index
favorite GET /favorite/:stop_id(.:format) favorites#new
unfavorite GET /unfavorite/:stop_id(.:format) favorites#delete
issues GET /issues(.:format) issues#index
POST /issues(.:format) issues#create
new_issue GET /issues/new(.:format) issues#new
edit_issue GET /issues/:id/edit(.:format) issues#edit
issue GET /issues/:id(.:format) issues#show
PATCH /issues/:id(.:format) issues#update
PUT /issues/:id(.:format) issues#update
DELETE /issues/:id(.:format) issues#destroy
root GET / pages#dashboard
编辑2:针对给出的答案,我将方法更改为
test "get show page with valid line id" do
param_line = lines(:one)
assert_not_nil param_line
puts "id: #{param_line.id}"
get line_path, id: param_line.id
line = assigns(:line)
assert_equal param_line.id, line.id
assert_response :success
end
运行在测试
时得到这个错误
# Running:
...id: 1
E
Error:
LinesControllerTest#test_get_show_page_with_valid_line_id:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"lines"} missing required keys: [:id]
test/controllers/lines_controller_test.rb:21:in `block in <class:LinesControllerTest>'
bin/rails test test/controllers/lines_controller_test.rb:16
对我来说似乎应该只是
get line_path(test_line_id)
在你的测试中。
说明:
无需将其包装在 params
中。 params
只是内部散列 Rails 提供给您的控制器操作以读取随请求传入的参数。您传递给路径生成器的第一个参数将始终映射到参数中的 id
。
因此您的代码将传入 params[:params]
– 由于我们有强大的参数,params[:params]
参数将被过滤掉(您应该在日志中看到关于此的警告)。
此外,正如我上面已经评论过的和@NicholasMartinez 指出的那样,您应该使用 _path
而不是 _url
,除非您明确需要绝对路径(例如在应用程序外部使用的链接中,例如在电子邮件中)。
我正在使用 Rails 5. 我的控制器中有以下方法
class LinesController < ApplicationController
...
def show
@line = Line.find(params[:id])
end
使用minitest,我想测试这个方法,所以我把这个写成我的测试...
test "get show page with valid line id" do
test_line_id = 1
get line_url, params: {id: test_line_id}
line = assigns(:line)
assert_equal test_line_id, line.id
assert_response :success
end
但是当我 运行 测试时出现以下错误....
Error:
LinesControllerTest#test_get_show_page_with_valid_line_id:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"lines"} missing required keys: [:id]
test/controllers/lines_controller_test.rb:16:in `block in <class:LinesControllerTest>'
bin/rails test test/controllers/lines_controller_test.rb:14
当我将 ID 作为参数传递时,为什么会出现关于 ID 的错误提示?
编辑:什么抽成路线returns
localhost:myproject davea$ rake routes
Prefix Verb URI Pattern Controller#Action
rails_settings_ui /settings RailsSettingsUi::Engine
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
page GET /pages/:page_name(.:format) pages#show
lines GET /lines(.:format) lines#index
line GET /lines/:id(.:format) lines#show
get_stops GET|POST /lines/:line_id/get_stops(.:format) lines#get_stops
stop GET /stops/:stop_id(.:format) stops#show
search GET /search(.:format) pages#search
favorites GET /favorites(.:format) favorites#index
favorite GET /favorite/:stop_id(.:format) favorites#new
unfavorite GET /unfavorite/:stop_id(.:format) favorites#delete
issues GET /issues(.:format) issues#index
POST /issues(.:format) issues#create
new_issue GET /issues/new(.:format) issues#new
edit_issue GET /issues/:id/edit(.:format) issues#edit
issue GET /issues/:id(.:format) issues#show
PATCH /issues/:id(.:format) issues#update
PUT /issues/:id(.:format) issues#update
DELETE /issues/:id(.:format) issues#destroy
root GET / pages#dashboard
编辑2:针对给出的答案,我将方法更改为
test "get show page with valid line id" do
param_line = lines(:one)
assert_not_nil param_line
puts "id: #{param_line.id}"
get line_path, id: param_line.id
line = assigns(:line)
assert_equal param_line.id, line.id
assert_response :success
end
运行在测试
时得到这个错误# Running:
...id: 1
E
Error:
LinesControllerTest#test_get_show_page_with_valid_line_id:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"lines"} missing required keys: [:id]
test/controllers/lines_controller_test.rb:21:in `block in <class:LinesControllerTest>'
bin/rails test test/controllers/lines_controller_test.rb:16
对我来说似乎应该只是
get line_path(test_line_id)
在你的测试中。
说明:
无需将其包装在 params
中。 params
只是内部散列 Rails 提供给您的控制器操作以读取随请求传入的参数。您传递给路径生成器的第一个参数将始终映射到参数中的 id
。
因此您的代码将传入 params[:params]
– 由于我们有强大的参数,params[:params]
参数将被过滤掉(您应该在日志中看到关于此的警告)。
此外,正如我上面已经评论过的和@NicholasMartinez 指出的那样,您应该使用 _path
而不是 _url
,除非您明确需要绝对路径(例如在应用程序外部使用的链接中,例如在电子邮件中)。