FactoryGirl和Rspec

时间:2011-12-08 23:40:55

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

我对这个TDD业务非常环保,所以任何帮助都会很棒!

所以,我有一家工厂有以下内容:

FactoryGirl.define do

  factory :account do
    email "example@example.com"
    url "teststore"
  end  

end

用Rspec测试:

  it "fails validation without unique email" do
    account1 = FactoryGirl.create(:account)
    account2 = FactoryGirl.create(:account)
    account2.should have(1).error_on(:email)
end

我因以下消息而失败:

  1) Account fails validation without unique email
     Failure/Error: account2 = FactoryGirl.create(:account)
     ActiveRecord::RecordInvalid:
       Validation failed: Email taken, please choose another, Url taken, please choose another
     # ./spec/models/account_spec.rb:11:in `block (2 levels) in <top (required)>'

这是创建新工厂的正确方法吗?任何想法我在这里做错了(我毫不怀疑我做 完全不正确!)

编辑:我想在第二个帐户上使用“创建”,我可能想要使用.build然后再使用.save吗?

2 个答案:

答案 0 :(得分:15)

保存自己的数据库交互,并使用build方法来处理这种情况。

it "fails validation without unique email" do
  account1 = create(:account)
  account2 = build(:account)
  account2.should_not be_valid
  account2.should have(1).error_on(:email) 
end

您无需尝试为valid?创建帐户以返回false。您可以访问帐户上的errors对象,即使它只是内置在内存中。这将减少数据库交互,从而使您的测试更快。

您是否考虑过在工厂中使用序列?我不知道您的RSpec / FactoryGirl经验有多远,但您会发现以下内容非常有用。

<强> factories.rb

factory :account do
  sequence(:email) { |n| "user#{n}@example.com" }
  url "teststore"
end

每次在帐户工厂拨打buildcreate时,您都会收到独特的电子邮件。

请记住,您始终可以使用选项哈希为工厂中的属性指定值。因此,当您在帐户上测试您的唯一性验证时,您会做同样的事情。

it "fails validation without unique email" do
  account1 = create(:account, :email => "foo@bar.com")
  account2 = build(:account, :email => "foo@bar.com")
  account2.should_not be_valid
  account2.should have(1).error_on(:email) 
end

答案 1 :(得分:0)

试试这个:

FactoryGirl.create(:account)
lambda {
  FactoryGirl.create(:account)
}.should raise_error(ActiveRecord::RecordInvalid)

这会有所帮助 - 语法类似于你正在做的事情。

但是,搜索“rspec validate_uniqueness_of”会找到一些更优雅的方法,而不是像这样使用工厂女孩!