Rails 控制器(集成?)测试有问题
Trouble with Rails controller (integration?) test
我正在制作我的第一个 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.
您编写测试的方式看起来像是集成测试。但我个人会建议编写系统测试。因为我看到你创建了一个 update_description
member 路由只是为了更新 User 对象?那不是必需的 - 您的 User
资源已经具有 edit
和 update
操作,因此您可以删除该成员路由。
集成测试用于检查工作流程以及应用程序不同部分的交互方式。虽然系统检查用于用户交互 - 基本上您检查用户会在其浏览器中执行和查看的内容。此外,在我看来,用这种技术编写测试(至少在这个级别)要简单得多。
因此您的系统测试将如下所示:
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..
我正在制作我的第一个 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.
您编写测试的方式看起来像是集成测试。但我个人会建议编写系统测试。因为我看到你创建了一个 update_description
member 路由只是为了更新 User 对象?那不是必需的 - 您的 User
资源已经具有 edit
和 update
操作,因此您可以删除该成员路由。
集成测试用于检查工作流程以及应用程序不同部分的交互方式。虽然系统检查用于用户交互 - 基本上您检查用户会在其浏览器中执行和查看的内容。此外,在我看来,用这种技术编写测试(至少在这个级别)要简单得多。
因此您的系统测试将如下所示:
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..