Rails 使用 Devise:用户详细信息未在测试中更新(但在应用程序中有效)

Rails with Devise: user details not being updated in tests (but works in application)

我对新 Rails 应用程序的测试失败了,原因我无法理解。应用程序本身可以工作,但测试没有——我可以毫无问题地更新用户配置文件。

该测试用于更新用户配置文件详细信息,由 Devise registrations_controller 控制。我没有覆盖控制器的这一部分,所以那里的代码是普通的。

测试代码:

sign_in @admin
get user_path(@admin)
assert_response :success
assert_template 'users/show'
assert_select "p.user-name", text: @admin.name
assert_select "p.user-email", text: @admin.email
#Can edit own user profile
new_name="New name"
put user_registration_path, params: {user: {name: new_name, email: @admin.email, current_password: 'password123'}}
get user_path(@admin)
assert_select "p.user-name", text: new_name

夹具:

admin:
  id: 11
  email: $LABEL@example.com
  name: $LABEL
  slug: $LABEL
  encrypted_password: <%= Devise::Encryptor.digest(User, 'password123') %>
  admin: true
  organisation_id: 1

当我 运行 测试时,它在最后的 assert_select 处产生错误 "<New name> expected but was <admin>.. Expected 0 to be >= 1.",表示记录未更新

byebug 的广泛使用表明错误是由于记录未在 Devise update 控制器中更新而导致的,导致它沿着 else 路线在line 57。但是,当我可以在应用程序中更新配置文件时,我不明白为什么这在测试中不起作用!

如果我用 @admin.update_columns(name: new_name) 替换 put ... 行然后测试通过,所以我的 put 命令肯定看起来有问题,这很奇怪,因为同一行有效在之前的 Rails 申请中。 (我已经尝试 patch 得到相同的结果,尽管应用程序中的工作表单使用 put 这就是我在测试中坚持使用它的原因。)

来自应用程序的工作表单代码(删除了 HTML 废话):

<%= form_for(@user, url: registration_path(@user), html: { method: :put, id: 'edit-user-account' }) do |f| %>
    <%= f.label :name %><br/>
    <%= f.text_field :name, autofocus: true, autocomplete: "Name", class: "form-control form-control-lg" %>

    <%= f.label :email %><br/>
    <%= f.email_field :email, autofocus: true, autocomplete: "email@example.com", class: "form-control form-control-lg" %>

    <%= f.label :password %>
    <i>(leave blank if you don't want to change it)</i><br/>
    <%= f.password_field :password, autocomplete: "new-password", class: "form-control form-control-lg" %>

    <%= f.label :password_confirmation %><br/>
    <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "form-control form-control-lg" %>

    <%= f.label :current_password %>
    <%= f.password_field :current_password, autocomplete: "current-password", class: "form-control form-control-lg" %>

    <%= f.submit "Update", class: "btn btn-lg btn-primary" %>
<% end %>

非常感谢收到任何建议!

Ruby 2.6.3,Rails 5.2.3,设计 4.6.2,minitest 5.11.3,rails-控制器测试 1.0.2

====编辑====

鉴于下面的评论链,我想我应该包括我的路线,所以设置是什么很清楚。

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)                                                                           users/registrations#cancel
new_user_registration GET        /users/sign_up(.:format)                                                                          users/registrations#new
edit_user_registration GET       /users/edit(.:format)                                                                             users/registrations#edit
user_registration     PATCH      /users(.:format)                                                                                  users/registrations#update
                      PUT        /users(.:format)                                                                                  users/registrations#update
                      DELETE     /users(.:format)                                                                                  users/registrations#destroy
                      POST       /users(.:format)                                                                                  users/registrations#create
                      GET        /users/sign_up/:e/:cid/:token(.:format)                                                           users/registrations#create
organisation_tags     GET        /organisation/:organisation_id/tags(.:format)                                                     tags#index
                      POST       /organisation/:organisation_id/tags(.:format)                                                     tags#create
organisation_tag      DELETE     /organisation/:organisation_id/tags/:id(.:format)                                                 tags#destroy
organisation_dashboard_layouts GET /organisation/:organisation_id/dashboards(.:format)                                             dashboard_layouts#index
organisation_dashboard_layout GET  /organisation/:organisation_id/dashboards/:id(.:format)                                         dashboard_layouts#show
                      PATCH      /organisation/:organisation_id/dashboards/:id(.:format)                                           dashboard_layouts#update
                      PUT        /organisation/:organisation_id/dashboards/:id(.:format)                                           dashboard_layouts#update
organisation_remove_dashboard_tag DELETE     /organisation/:organisation_id/organisation/:organisation_id/dashboards/:id/tag/:tag_id(.:format) dashboard_layouts#remove_tag
organisation          GET        /organisation/:id(.:format)                                                                       organisations#show
user                  GET        /profiles/:id(.:format)                                                                           users#show
add_user_tag          PATCH      /profiles/:id(.:format)                                                                           users#add_user_tag
remove_user_tag       DELETE     /profiles/tag/:id(.:format)                                                                       users#remove_user_tag
profile_toggle_org_admin PATCH   /profiles/toggle_org_admin/:id(.:format)                                                          users#toggle_org_admin
invited_users         POST       /invited_users(.:format)                                                                          invited_users#create
resend_invitation_email POST     /invited_users/resend/:id(.:format)                                                               invited_users#resend_invitation_email

我想你忘了将用户对象传递给用户注册路径

put user_registration_path(@admin)

这背后的原因最终是测试数据库不是最新的。我删除并重新创建了测试数据库(使用 rails db:drop RAILS_ENV=testrails db:create RAILS_ENV=test),测试开始按预期运行。