1

我写了一个测试,应该描述@user 和 found_user 应该通过密码匹配相同的情况。这也描述了它们何时不同。我没有使用设计或任何东西,而是建立自己的身份验证has_secure_password

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

失败的部分是with a valid password块。错误消息清楚地表明password_digest不匹配

这是相关的输出:

expected: password_digest: "$2a$04$cDKhuWzsZuW8Gm4t5fJjpu6rmbwh10ZAt2Yae.BO0iuD...">
got: password_digest:      "$2a$04$jwfHjoLI0RpDIAEr9SMKGOZqeH.J5ILOkzalKCYQdDW4...">

我曾尝试删除 before 块中的 @user.save ,认为这可能会解决它,但它没有。

我不确定他们为什么会出现不同的情况,或者我做错了什么。我对 rspec 和一般测试还很陌生。

我应该提到我的身份验证方法在 rails 控制台中工作。因此,我遇到了应用程序代码可以正常工作但测试失败的情况。

任何帮助将非常感激。

我的用户类在这里:https ://gist.github.com/DavidVII/f190d1f1e114234bb7d7

谢谢!

4

1 回答 1

4

您的测试不适用于 bcrypt 密码散列(我可以从字符串的形式中看出您正在使用什么),因为它会为每次密码更改生成一个新的随机盐。这是一件好事,不要改变这种行为。

所以你不应该编写测试来寻找存储的密码等于已知值。如果您打算在测试中这样做,或者由于您通过 using 获得的所有抽象而意外地过度简化了测试has_secure_pasword,或者其他一些事情导致您使用当前代码,目前还不是 100% 清楚。

相反,您围绕密码处理的测试应该更加黑盒,并断言您可以使用已知密码登录,而不是使用任何其他密码登录(包括诸如 nil、空字符串、超长密码和与哈希密码匹配的字符串)。

于 2013-05-17T08:28:34.980 回答