我对这个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吗?答案 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
每次在帐户工厂拨打build
或create
时,您都会收到独特的电子邮件。
请记住,您始终可以使用选项哈希为工厂中的属性指定值。因此,当您在帐户上测试您的唯一性验证时,您会做同样的事情。
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”会找到一些更优雅的方法,而不是像这样使用工厂女孩!