我无法通过有效的密码测试

时间:2013-05-18 23:07:53

标签: ruby-on-rails ruby rspec

我正在尝试通过有效的密码测试。当我运行它时,似乎password_digest哈希是不同的。我不知道如何让它们匹配。

我主要使用Michael Hartl撰写的“Ruby on Rails教程:通过示例学习Rails”这本书,看起来他已经通过了。

此外,我的应用程序代码正常工作。我可以创建一个用户并在控制台中对它们进行身份验证,这样只会在测试中中断。

我对测试很新,所以我可能会遗漏一些明显的东西。

感谢您的帮助!

我正在使用带有has_secure_password的bcrypt,这里是部分相关用户规范代码:

describe User do

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

  subject { @user }

  it { should respond_to(:name) }
  it { should respond_to(:email) }
  it { should respond_to(:password_digest) }
  it { should respond_to(:password) }
  it { should respond_to(:password_confirmation) }
  it { should respond_to(:authenticate) }

  it { should be_valid }

  describe "return value of authenticate method" do
    before { @user.save }
    let(:found_user) { User.find_by(email: @user.email) }

    describe "with a valid password" do
      it { should eq found_user.authenticate(@user.password) }
    end

    describe "with an invalid password" do
      let(:user_for_invalid_password) { found_user.authenticate('invalid') }

      it { should_not eq user_for_invalid_password }
      specify { expect(user_for_invalid_password).to be_false }
    end
  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]+)*\.[a-z]+\z/i
  validates :email, presence: true, uniqueness: { case_sensitive: false }, format: { with: VALID_EMAIL_REGEX }

  has_secure_password
  validates :password_confirmation, presence: true
  validates :password, length: { minimum: 6 }
end

1 个答案:

答案 0 :(得分:2)

问题出在before { @user.save }。您可能没有意识到,但before默认为before(:each),这意味着此代码在组中的每个示例之前运行。您可能希望它默认为before(:all),它只运行一次,然后才会在组中的所有示例之前运行。

正如您所提到的,每次测试后都没有清除数据库。因此,在每次测试之前,您都在调用@user.save。由于您尝试使用相同的电子邮件地址创建另一个用户,因此通过返回false默认无效验证。最好使用#save!,以便抛出验证异常,使这样的问题变得更加明显。

总结:

  • 明确使用before(:all)before(:each)
  • 使用#save!代替#save
  • 在每次测试之间清除数据库(试用Database Cleaner