繁体   English   中英

如何在 Model Rails 中使用条件测试验证

[英]How to test a validation with conditional in a Model Rails

我想知道是否必须在特定条件下测试 model。 假设我有一个需要国家/地区验证的用户 model。 该国家/地区验证已在平台创建后 12 个月以上设置,因此,我们有一些用户没有验证国家/地区(或没有任何国家/地区)

这就是为什么我们有一个allow_nil: true

但是我们遇到了一个问题。 其中一位用户需要重置他/她的密码,但由于该国家/地区不是有效国家/地区,因此他/她无法重置他/她的密码。

所以这就是我发现解决这个问题的方法:

unless: -> { reset_password_token.present? }

class User < Applicationrecord

VALID_COUNTRY_NAMES = ['Afghanistan', 'Åland', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda'....]

validates :country, allow_nil: true, inclusion: { in: VALID_COUNTRY_NAMES }, unless: -> { reset_password_token.present? }
end

问题:我如何测试这个特定条件(具有无效国家的用户想要重置密码?

我对这个问题有点犹豫,我不得不承认测试对我来说并不容易。

解决方案

感谢@AbM,我可以通过以下测试解决它:

it 'allows existing user to reset password' do
  user = build(:user, country: 'invalid', reset_password_token: 'some_value')
  expect(user.reset_password_token).to eq('some_value')
  expect(user).to be_valid
end

我仍然不知道为什么我为一个如此简单的测试而奋斗了这么多!

不要使用to be_valid匹配器。 当它失败时,它不会告诉你关于被测实际行为的任何信息。

一个真正的问题是,您在 model 上一次测试每一个验证,所以它确实比您的验证更多地说明了您的工厂/固定装置。

相反,只需使用有效或无效数据(排列)设置 model 并调用#valid? 触发验证(动作),然后根据 rails 提供的ActiveModel::Errors API编写期望(断言)。

context "when the user does not have a password reset token" do
  let(:user) do
    User.new(
      country: 'Lovely'
    )
  end
  it "does not allow an invalid country" do
    user.valid?
    expect(user.errors.details[:country]).to include { error: :inclusion, value: "Lovely" }
  end
end

context "when the user has a password reset token" do
  let(:user) do
    User.new(
      country: 'Lovely',
      reset_password_token: 'abcdefg'
    )
  end

  it "allows an invalid country" do
    user.valid?
    expect(user.errors.details[:country]).to_not include { error: :inclusion, value: "Lovely" }
  end
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM