使用FactoryGirl Rspec的模型验证失败,验证似乎被忽略

时间:2013-04-20 18:39:50

标签: ruby-on-rails validation rspec

我的Rails模型验证测试存在问题。验证功能正常(它拒绝格式错误的电子邮件),但测试失败。

以下是我的user.rb模型中的重要信息

class User < ActiveRecord::Base

  attr_accessible :first_name, :middle_name, :last_name, :email, :password, :address, :city, :state, :zip_code, :phone_home, :phone_cell, :phone_work, :status_id, :password_confirmation, :is_test, :parent_paramed_id, :company, :logo, :is_agent, :is_paramed, :additional_emails

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validate :validates_single_email_format
  validates_presence_of :email
  validates_uniqueness_of :email

  def validates_single_email_format
    User.validates_single_email_format(self.email)
  end

  def self.validates_single_email_format(email)
    email =~ VALID_EMAIL_REGEX
  end

这是我的user_spec.rb

describe User do
  context "validate email address on create" do
    before { User.delete_all }

    context "fails" do
      let(:user) { FactoryGirl.build(:user, :email => 'blah') }
      before { user.save; binding.pry }
      specify { user.should_not be_valid }
    end

    context "succeeds" do
      let(:user) { FactoryGirl.build(:user, :email => 'matt@google.com' ) }
      before { user.save; binding.pry }
      specify { user.should be_valid }
    end

  end
end

这是此测试的输出,因为它在每次保存后使用binding.pry执行,以查看调用save后用户对象的样子:

From: /project/spec/models/user_spec.rb @ line 96 :

     91:   context "validate email address on create" do
     92:     before { User.delete_all }
     93:
     94:     context "fails" do
     95:       let(:user) { FactoryGirl.build(:user, :email => 'blah') }
 =>  96:       before { user.save; binding.pry }
     97:       specify { user.should_not be_valid }
     98:     end
     99:
    100:     context "succeeds" do
    101:       let(:user) { FactoryGirl.build(:user, :email => 'matt@google.com' ) }

[1] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_4::Nested_1>)> user
=> #<User id: 178, first_name: "Martha", middle_name: nil, last_name: "Magdalena", email: "blah", additional_emails: nil, password_hash: "$2a$10$HF1t3cIwQiwj7PN/DkBgwOJw667FFixFB3srksZypHxR...", password_salt: "$2a$10$HF1t3cIwQiwj7PN/DkBgwO", password_reset_token: nil, password_reset_sent_at: nil, address: nil, city: nil, state: nil, zip_code: nil, phone_home: nil, phone_cell: nil, phone_work: nil, status_id: 1, is_test: false, parent_paramed_id: nil, company: nil, logo: nil, is_agent: true, is_paramed: false, created_at: "2013-04-20 18:13:02", updated_at: "2013-04-20 18:13:02">
[2] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_4::Nested_1>)> exit
F
From: /project/spec/models/user_spec.rb @ line 102 :

     97:       specify { user.should_not be_valid }
     98:     end
     99:
    100:     context "succeeds" do
    101:       let(:user) { FactoryGirl.build(:user, :email => 'matt@google.com' ) }
 => 102:       before { user.save; binding.pry }
    103:       specify { user.should be_valid }
    104:     end
    105:
    106:   end
    107:

[1] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_4::Nested_2>)> user
=> #<User id: 179, first_name: "Martha", middle_name: nil, last_name: "Magdalena", email: "matt@google.com", additional_emails: nil, password_hash: "$2a$10$LEA28MGLIdLuk6lPEPGmH.lW3QwkR9KoXgbULPHJZa4v...", password_salt: "$2a$10$LEA28MGLIdLuk6lPEPGmH.", password_reset_token: nil, password_reset_sent_at: nil, address: nil, city: nil, state: nil, zip_code: nil, phone_home: nil, phone_cell: nil, phone_work: nil, status_id: 1, is_test: false, parent_paramed_id: nil, company: nil, logo: nil, is_agent: true, is_paramed: false, created_at: "2013-04-20 18:13:11", updated_at: "2013-04-20 18:13:11">
[2] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_4::Nested_2>)> exit
.

Failures:

  1) User validate email address on create fails
     Failure/Error: specify { user.should_not be_valid }
       expected valid? to return false, got true
     # ./spec/models/user_spec.rb:97:in `block (4 levels) in <top (required)>'

Finished in 16.9 seconds
2 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:97 # User validate email address on create fails

由于某种原因,即使将电子邮件值视为“等等”,失败的测试也会返回true。如果我在对象上运行验证方法,它会通过说没有匹配来响应。但由于某种原因“预期有效?”测试返回true。我不确定为什么会这样。

非常感谢任何帮助。我可以在现有问题中找到任何类似的问题。

编辑:删除路径中的计算机特定信息

2 个答案:

答案 0 :(得分:1)

两件事。您的validates_single_email_format方法不仅需要返回false,还必须调用errors.add(:email, "Email is in wrong format!")才能产生效果。

valid?方法不仅运行验证,还将错误消息添加到errorserrors最后为空,然后模型被视为有效。

无论如何,你可以使用:

validates_format_of :email, with: VALID_EMAIL_REGEX

答案 1 :(得分:1)

验证语法不正确。只需两行就可以尝试这个正确的。

EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, uniqueness: true, format: {with: EMAIL_REGEX}