Rails控制器(集成?)测试问题

时间:2017-10-29 04:19:54

标签: ruby-on-rails testunit

我正在制作我的第一个Rails应用程序,所以这可能是基本的。

在我的用户个人资料中,我想让用户添加标题和说明。我将它们作为User模型的属性,并将其添加到routes.rb

  resources :users do
    member do
      post 'update_description'
    end
  end

同样的方法(尚未编写)将处理这两个属性。为了练习TDD,我想编写一个测试,只是表明,如果用户提交标题,那么控制器会将其保存到数据库中。我认为这将是一个集成测试,但我无法正确的路径。 (应该它是一个集成测试?)然后,通过研究,我设法在相关的控制器测试文件中编写了一个工作post语句。这是控制器测试:

  test "profile submits new title and description successfully" do
    log_in_as(@user)
    get :show, id: @user
    assert_nil @user.title
    post :update_description, id: @user, params: { title: "Lorem ipsum" }
    # Next:
    # @admin.reload.title
    # assert @admin.title == "Lorem ipsum"
    # assert_template 'users/show'
    # Etc.

  end

这会引发以下错误:

ERROR["test_profile_submits_new_title_and_description_successfully", UsersControllerTest, 2017-10-22 21:42:52 -0400]
 test_profile_submits_new_title_and_description_successfully#UsersControllerTest (1508722972.17s)
ActionView::MissingTemplate:         ActionView::MissingTemplate: Missing template users/update_description, application/update_description with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
          * "/var/lib/gems/2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates"
          * "/home/globewalldesk/startthis/app/views"
          * "/var/lib/gems/2.3.0/gems/web-console-2.0.0.beta3/app/views"

            test/controllers/users_controller_test.rb:83:in `block in <class:UsersControllerTest>'
        test/controllers/users_controller_test.rb:83:in `block in <class:UsersControllerTest>'

我认为这意味着Rails正在寻找一个视图文件并且找不到一个,但我不明白为什么post :update_description让它查找视图...我认为这将是发布信息没有视图(我有一个类似的路径,以相同的方式工作,没有视图)。 update_description方法位于Users控制器中。我已经做了很多研究,但我无法弄清楚我做错了什么。救命! TIA。

1 个答案:

答案 0 :(得分:1)

您编写测试的方式看起来像集成测试。但我个人会建议写一个系统测试。因为我看到你创建一个update_description成员路由只是为了更新User对象?这不是必需的 - 您的User资源已经有editupdate个操作,因此您可以删除该成员路由。

用于检查工作流程以及如何与应用程序的不同部分进行交互的集成测试。虽然系统检查是为了用户交互 - 基本上你检查用户将在他的浏览器中执行和查看的内容。在我看来,在这种技术中编写测试更简单(至少在这个级别)。

所以你的系统测试看起来像:

setup do
  log_in_as(@user) // or what ever code to visit login page and login user
end

test "profile submits new title successfully" do
  visit edit_user_path

  fill_in "Title", with: "Lorem ipsum"

  click_on "Save"

  assert_response :redirect
  follow_redirect!
  assert_select "Title", text: "Lorem ipsum"
end

这假设在用户提交表单后,应用重定向到user_path(@user)(显示页面)。

整合测试看起来像:

test "profile submits new title successfully" do
  log_in_as(@user) // or what ever code to login user
  get "/user/#{@user.id}/edit"
  assert_response :success

  updated_title = "Lorem ipsum"

  patch :update, user: { id: @user.id, title: updated_title }

  assert_response :redirect
  follow_redirect!
  assert_response :success
  assert_select "Title", text: "Lorem ipsum"
end

注意 - 我还没有测试过这个,我使用的是Capybara和其他工具,但不是Minitest。但是在这个简单的情况下我认为这应该是有用

如果你还没有这样做,请检查docs ..