预计至少有 1 个元素匹配 "div#error_explanation",找到 0.. 预计 0 为 >= 1

Expected at least 1 element matching "div#error_explanation", found 0.. Expected 0 to be >= 1

我是一个 rails 新手,无法在遵循 Hartl 的 Rails 教程时将此错误与代码联系起来。

这里的类似问题@Whosebug 没有解决我的特定测试失败错误消息的问题,因为我的部分代码与 github 上的 Hartl 代码相同,并且我的集成测试的所有其他方面都通过了绿色。

sample_app_3rd_edition/app/views/shared/_error_messages.html.erb

这是我的集成测试代码

/test/integration/password_resets_test.rb

       #Invalid password & confirmation
       patch password_reset_path(user.reset_token),
         email: user.email,
         user: { password:               "foobazz",
                 password_confirmation:  "barquux" }
       assert_select 'div#error_explanation'

它生成一条引用第 6 行的错误消息:

test_password_resets#PasswordResetsTest (1442030711.19s)
    Expected at least 1 element matching "div#error_explanation", found 0..
    Expected 0 to be >= 1.

接下来是部分

/app/views/shared/_error_messages.html.erb

assert_select 'div#error_explanation' 应该从中呈现无效密码和确认所需的错误消息。

/app/views/shared/_error_messages.html.erb

<% if @user.errors.any? %>
     <div id="error_explanation">
       <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count,"error") %>
       </div>
       <ul>
         <% @user.errors.full_messages.each do |msg| %>
           <li><%= msg %></li>
         <% end %>
       </ul>
    </div>
 <% end %>

我只是不明白为什么 assert_select 在这里不起作用,因为 _error_message 部分适用于引用相同部分的所有其他测试。我想我明白集成测试失败告诉我 "there is no message (element) where there should be one."

非常感谢帮助解决我的困惑!我很乐意 post UserController/ PasswordController 或任何需要的@user 变量代码。

15 年 10 月 10 日更新这里是 user.rb

class User < ActiveRecord::Base
   attr_accessor :remember_token, :activation_token, :reset_token
   before_save   :downcase_email
   before_create :create_activation_digest
   validates     :name, presence: true, length: {maximum:50}
   VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
   validates :email,presence: true, length: {maximum:255},
             format: { with: VALID_EMAIL_REGEX },
             uniqueness: { case_sensitive: false }
   has_secure_password
   validates :password, length: { minimum: 6 }, allow_blank: true

这是 PasswordResetsController

class PasswordResetsController < ApplicationController
   before_action :get_user,         only:[:edit, :update]
   before_action :valid_user,       only:[:edit, :update]
   before_action :check_expiration, only:[:edit, :update]
   def new
   end

   def create
     @user = User.find_by(email: params[:password_reset]     [:email].downcase)
     if @user
        @user.create_reset_digest
        @user.send_password_reset_email
        flash[:info] = "Email sent with password reset instructions"
        redirect_to root_url
     else
       flash.now[:danger] = "Email address not found"
       render 'new'
     end
   end


   def edit
   end

   def update
     if password_blank?
       flash.now[:danger] = "Password can't be blank"
       render 'edit'
     elsif @user.update_attributes(user_params)
       log_in @user
       flash[:success] = "Password has been reset"
       redirect_to @user
     else
       render 'edit'
     end
   end

   private

     def user_params
       params.require(:user).permit(:password,
                                    :password_confirmation)
     end

     #Returns true if password is blank.

     def password_blank?
       params[:user][:password].blank?
     end

     #Before filters

     def get_user
        @user = User.find_by(email: params[:email])
     end

     #Confirms a valid user.
     def valid_user
       unless (@user && @user.activated? && 
               @user.authenticated?(:reset, params[:id]))
       redirect_to root_url
       end
     end

     #Checks expiration of reset token
     def check_expiration
       if @user.password_reset_expired?
         flash[:danger] = "Password reset has expired."
         redirect_to new_password_reset_url
       end
     end
 end

查看您的用户模型 (user.rb)。在某处,应该有一行 has_secure_password。这是一个添加密码和 password_confirmation 虚拟属性及其验证的 Rails 方法。

这在 Hartl 教程的第 6.3.1 节中有解释。

在测试中,使用密码和 password_confirmation 属性创建了一个用户对象。发布到 password_reset_path 尝试保存此用户对象。每次模型对象尝试保存时,所有模型验证都是 运行。因此,如果没有此 has_secure_password 验证,则允许保存用户对象,因此您没有看到任何错误。

我猜您没有在 app/views/password_resets/edit.html.erb 表单中呈现 shared/_error_messages.html.erb。

<% provide(:title, 'Reset password') %>
<h1>Reset password</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>

      # Render the error messages!
      <%= render 'shared/error_messages' %>

      <%= hidden_field_tag :email, @user.email %>

确保插入正确,测试应该成功!

1) 失败:

HomeControllerTest#test_should_get_home [/home/ubuntu/workspace/test/controllers/home_controller_test.rb:11]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.