为什么这个规范不能按预期工作?

时间:2014-02-16 18:42:07

标签: ruby-on-rails ruby rspec

我查看堆栈溢出的答案,发现一些人发布了类似的问题,但解决方案没有帮助。据我所知,我的代码是完全正确的。

我正在关注以下教程: http://ruby.railstutorial.org/chapters/modeling-users#code-validates_uniqueness_of_email_case_insensitive_test

 require 'spec_helper'

describe User do

  before { @user = User.new(name: "Example User", email: "user@example.com") }

  subject { @user }

  it { should respond_to(:name) }
  it { should respond_to(:email) }

  it { should be_valid }

  describe "when name is not present" do
    before { @user.name = " " }
    it { should_not be_valid }
  end

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end

  describe "when name is too long" do
    before { @user.name = "a" * 51 }
    it { should_not be_valid }
  end

  describe "when email format is invalid" do
    it "should be invalid" do
      addresses = %w[user@foo,com user_at_foo.org example.user@foo. foo@bar_baz.com foo@bar+baz.com]
      addresses.each do | invalid_address |
        @user.email = invalid_address
        expect(@user).not_to be_valid
      end
    end
  end

  describe "when email format is valid" do
    it "should be valid" do
      addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
      addresses.each do | valid_address |
        @user.email = valid_address
        expect(@user).to be_valid
      end
    end
  end

  describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.email = @user.email.upcase
      user_with_same_email.save
    end
    #it "should not be valid" do
    #  expect(@user).not_to be_valid
    #end
    it { should_not be_valid }

  end


end

最后一条规格失败。

我的用户验证是这样的:

class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensative: false }
end

我完美地遵循了教程,但我似乎无法使此验证正常工作。我知道这个教程有点旧,我可能会使用一些新的宝石。我也知道这不是进行此类验证的最佳方法,但教程只是让它一开始变得非常简单。这是怎么回事?

谢谢!


修改 没有错误。当验证成功时,验证会失败。

Failures:
1) User when email address is already taken should not be valid
Failure/Error: it { should_not be_valid }
expected #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil> not to be valid
# ./spec/models/user_spec.rb:58:in `block (3 levels in <top (required)>'

Finished in 0.09887 seconds
1 example, 1 failure

再次编辑。 user_spec.rb已完全粘贴在任务中。对不起,我对ruby很陌生,并没有意识到可能需要帮助排除故障。

3 个答案:

答案 0 :(得分:2)

如果您继续阅读本教程,您会发现作者说测试仍未完成传递。那是因为当前的验证仍然区分大小写。

添加uniqueness: { case_sensitive: false }会使测试按预期传递

validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }

答案 1 :(得分:0)

我认为它刚刚解决了。也许有人可以解释刚刚发生的事情。我决定继续学习本教程并将gem 'bcrypt-ruby', '3.1.2'添加到gemfile中。然后我跑了bundle install

然后我尝试运行rspec spec/并返回错误:

Migrations are pending; run 'bin/rake db:migrate RAILS_ENV=development' to resolve this issue.

但当我跑rake db:migrate时,什么也没发生。所以我用Google搜索并找到了this SO post a solution

我跑了:

rake test:prepare 
rake db:migrate

然后所有测试都通过了。

也许我的测试环境对我疯狂了?我仍然不知道刚刚发生了什么。

答案 2 :(得分:0)

您可以在user_with_same_email.valid?之前添加.save并提供其输出,但我相信它会true,因为:

  1. 您尚未更改id的{​​{1}}

  2. 您只需更改的大小写,但它也同样有效,因此“A@A.COM”和“a@a.com”相同且有效。< / p>

  3. @user返回#valid,因为true存在,有良好的:email,并且仍然是唯一的。