factory_girls序列和唯一性

时间:2011-05-13 14:18:57

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

我在factories.rb中有这个设置。

Factory.sequence(:email) { |n| "email#{n}@factory.com" }
Factory.sequence(:username) { |n| "username_#{n}" }

Factory.define :user do |u|
  u.email { Factory.next :email }
  u.username { Factory.next :username }
  u.first_name 'Ivan'
  u.last_name 'Pupkin'
  u.latitude '42'
  u.longitude '-71'
  u.password 'qwerty'
  u.password_confirmation 'qwerty'
end

当我创建Factory的两个实例(:用户)时,我得到了唯一性错误。

describe CartsController do

  let(:user) { Factory(:user) }
  let(:another_user) { Factory(:user) }
  let(:cart) { Factory(:cart) }


  describe 'show my cart' do
    before { sign_in user}
    before { get :show, :id => user.carts.last }
    it { should respond_with :success }
  end

  describe 'show different person cart' do
    before { sign_in user }
    before { get :show, :id => another_user.carts.last}
    it { should respond_with :redirect }
  end
end

我的问题在哪里?

Failure/Error: let(:user) { Factory(:user) }
Validation failed: Username has already been taken, Email has already been taken

2 个答案:

答案 0 :(得分:3)

似乎您的数据库中有记录,因为let(:user) { Factory(:user) }失败而let(:another_user) { Factory(:user) }失败,所以我看到两种可能的解决方案:在顶部添加User.delete_all或手动清理数据库

答案 1 :(得分:1)

是的,这是测试数据库中的剩余部分。您应该在spec_helper.rb中包含以下行:

  config.use_transactional_fixtures = true

请注意,即使您使用的是工厂而不是固定装置,这也很有用。它将每个示例包装在数据库事务中,以便每次都有一个干净的平板。如果您没有使用ActiveRecord,或者由于任何其他原因导致事务不适合您,则需要在每次测试运行后引入类似database_cleaner gem的内容来清理测试数据库。