简体   繁体   English

在使用shoulda-matchers和factory-girl-rails测试Rails模型验证时遇到问题吗?

[英]Having trouble testing Rails Model validations with shoulda-matchers and factory-girl-rails?

Model: 模型:

validates :email,
uniqueness: {
  message: "has been taken."
},
presence: {
  message: "cannot be blank."
},
length: {
  minimum: 3,
  message: "is too short, must be a minimum of 3 characters.",
  allow_blank: true
},
format: {
  with: /\A[A-Z0-9_\.&%\+\-']+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,13})\z/i,
  message: "is invalid.",
  if: Proc.new { |u| u.email && u.email.length >= 3 }
}

RSpec: RSpec的:

before(:each) do
  @user = FactoryGirl.build(:user)
end

it { should validate_length_of(:email).is_at_least(3) }

Error: 错误:

Failure/Error: should validate_length_of(:email).is_at_least(3)
   Expected errors to include "is too short (minimum is 3 characters)" when email is set to "xx",
   got errors:
   * "is too short (minimum is 4 characters)" (attribute: password, value: nil)
   * "is too short, must be a minimum of 3 characters." (attribute: email, value: "xx")
   * "is not included in the list" (attribute: state, value: "passive")

Factory: 厂:

factory :user, class: User do
  email FFaker::Internet.email
  password FFaker::Internet.password
  username FFaker::Internet.user_name

end

I am using factory_girl_rails with shoulda_matchers. 我正在将factory_girl_rails与shoulda_matchers一起使用。 Every time I try to validate my email, I keep getting an error like above. 每次尝试验证电子邮件时,都会不断出现上述错误。 It says the email value is "xx", but the length of the factory email is greater than that. 它说电子邮件的值为“ xx”,但是工厂电子邮件的长度大于该长度。 How can I write an rspec that will pass? 如何编写将通过的rspec?

You are understanding the error (and it's cause) wrong. 您正在理解错误(及其原因)错误。 The error says that it expects "is too short (minimum is 3 characters)" but in the errors it can't find that string (rspec finds "is too short, must be a minimum of 3 characters." which is what you defined on your validation). 该错误表明它期望“太短(至少3个字符)”,但在错误中找不到该字符串(rspec发现“太短,必须至少3个字符。”这就是您定义的根据您的验证)。

When you use shoulda matchers and say 当你使用大锅火柴说

it { should validate_length_of(:email).is_at_least(3) }

I'm guessing it creates a test with an email shorter than 3 and checks if it fails, that's why it's ignoring your factory, internally should matcher is setting a fixed length string just to make that test pass. 我猜想它会创建一个电子邮件短于3的测试,并检查它是否失败,这就是为什么它忽略了您的工厂,内部匹配器应该设置固定长度的字符串以使其通过测试。

When you see the errors in user, that test should actually work since the error is actually there, only the string is different. 当您在用户中看到错误时,该测试应实际上可以正常进行,因为错误实际上存在于此,只是字符串不同。 So, you have two options: remove the custom message when length is minimum: 3; 因此,您有两个选择:长度最小时删除自定义消息:3; or tell the matcher what message you are expecting: 或告诉匹配者您期望什么消息:

it { should validate_length_of(:email).is_at_least(3).with_message("is too short, must be a minimum of 3 characters.") }

Shoulda-matchers tests validations by testing the messages in the errors object. Shoulda-matchers应该通过测试错误对象中的消息来测试验证。

The valdation matchers only work with the rails default error messages unless you specify otherwise: 验证匹配器仅与rails默认错误消息一起使用,除非您另外指定:

it { should validate_length_of(:email).with_message("is too short, must be a minimum of 3 characters.") }

The with_message method is detailed in this comment . 注释中详细介绍了with_message方法。

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

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