在为Rails控制器方法编写测试时,如何将ID参数传递给show方法?

时间:2018-01-02 20:06:49

标签: parameters controller ruby-on-rails-5 show minitest

我正在使用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?

编辑:返回哪些佣金路线

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

1 个答案:

答案 0 :(得分:2)

对我而言似乎应该只是

get line_path(test_line_id)

在你的测试中。

说明: 无需将其包含在params中。 params只是Rails为您的控制器操作提供的内部哈希值,用于读取随请求传入的参数。传递给路径生成器的第一个参数将始终映射到参数中的id

因此,您的代码会传入params[:params] - 由于我们有强大的参数,params[:params]参数将被过滤掉(您应该在日志中看到有关此问题的警告)。

另外,正如我上面已经评论的那样,@ NicholasMartinez指出,你应该使用_path而不是_url,除非你明确需要一个绝对路径(比如在应用程序之外使用的链接,例如在电子邮件中。)