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

时间:2015-10-10 00:13:32

标签: ruby-on-rails ruby ruby-on-rails-3

我是一个铁杆菜鸟&在遵循Hartl的Rails教程时,无法连接此错误和代码。

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

sample_app_3rd_edition /应用/视图/共享/ _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部分适用于引用相同部分的所有其他测试。我想我明白,集成测试失败告诉我“没有消息(元素)应该有一个消息。”

非常感谢帮助清除我的困惑!我很乐意发布UserController / PasswordController或者需要@user变量代码。

更新10/10/15这里是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

3 个答案:

答案 0 :(得分:2)

我猜您没有在 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 :(得分:0)

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

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

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

答案 2 :(得分:0)

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.