FactoryGirl没有给出有用的验证错误

时间:2012-03-22 15:32:31

标签: ruby-on-rails rspec factory-bot

我正在使用FactoryGirl作为我的灯具,我发现它并没有真正产生有用的验证错误。

我总是收到有关activerecord.errors.models.messages.record_invalid的消息。

不确定需要哪些进一步的细节来帮助诊断。这使得跟踪每个错误的过程非常缓慢。

示例工厂:

Factory.define :partner do |partner|
  partner.sequence(:username){ |n| "amcconnon#{n}" }
  partner.first_name            "Bobby Joe"
  partner.last_name             "Smiley"
  partner.sequence(:email){ |n| "bob{n}@partners.com" }
  partner.phone_number          "5557 5554"
  partner.country_id            75
  partner.password              "password"
  partner.password_confirmation "password"
end

然后工厂(:合作伙伴)=> “ActiveRecord :: RecordInvalid异常:看起来这些更改出了问题”

实际问题当然是电子邮件序列没有正确使用n,并且电子邮件上有唯一的验证。但这只是为了说明目的。

rails => 3.2.2 factory_girl 2.6.1

还需要其他任何帮助诊断此问题的deets?

(注意:编辑这只是为了添加一个更容易阅读的工厂)

编辑:

根据bijan的评论:“我到底想做什么。”

尝试运行“rspec spec”。我希望当我在这种情况下使用像Factory(:partner)这样的工厂作为错误消息时,如果它不能包含我从Partner.new({blah ...})得到的相同错误。有效吗?然后看了验证失败。

2 个答案:

答案 0 :(得分:3)

我不确定这是否与您遇到的问题完全相同,但是我遇到的问题是验证错误消息不是很有用,我认为这对其他搜索此问题的人有用。以下是我提出的建议。这可以修改为提供不同的信息。

include FactoryGirl::Syntax::Methods

# Right after you include Factory Girl's syntax methods, do this:

def create_with_info(*args, &block)
  create_without_info(*args, &block)
rescue => e
  raise unless e.is_a? ActiveRecord::RecordInvalid
  raise $!, "#{e.message} (Class #{e.record.class.name})", $!.backtrace
end
alias_method_chain :create, :info

然后,当您使用create :model_name时,它将始终在错误消息中包含模型名称。我们有一些相当深的依赖(是的,另一个问题),并且有一个验证错误,例如“名称无效”...... name是几个不同模型的属性。添加此方法后,可节省大量调试时间。

答案 1 :(得分:0)

我认为这里的关键点是,当您设置测试时,您需要确保您测试的代码在您设置期望时失败(即当您在Rspec中说“应该”时)。测试验证的具体问题当然是,一旦您尝试保存ActiveRecord对象,验证就会失败;因此测试设置不得调用save。

具体建议:

1)IMO工厂定义应包含创建有效对象所需的最少信息,并且应尽可能少地更改。如果要测试验证,可以在实例化新测试对象时覆盖正在测试的特定属性。

2)测试验证时,请使用Factory.buildFactory.build使用指定的属性创建ActiveRecord实例,但不尝试保存它;这意味着您可以暂停触发验证,直到您在测试中设置期望值。

这样的事情怎么样?

it "should fail to validate a crap password" do
  partner_with_crap_password = Factory.build(:partner, :password => "crap password")
  partner_with_crap_password.should_not be_valid
end