在Rails Factory Girl中创建重复记录

时间:2013-11-22 13:41:42

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

当我运行rspec时,有时所有测试都通过。但偶尔它会失败。它说Validation failed: Nyaaid has already been taken。看起来Factory girl偶尔会创建重复的条目。

这是我的工厂女孩​​代码:

factory :awardunit do
    sequence(:name)  { |n| "Person #{n}" }
    nyaaid { "NYAA/N/WP#{ [1,1,1,1].map!{|x| (3..9).to_a.sample}.join }" }
    address "Example Address"
    district "Colombo"
    contact ["23232223"]
    sequence(:email) { |n| "person_#{n}@example.com"}
    insthead "Example Person"
    instheadcontact ["232324223"]
    datestarted "2013-08-04"
    allowedmem 8
    remarks "No"
    disabled false
end

这是我的测试:

    ### Award Unit List

    describe "pagination" do

      before(:all) do 
        30.times { FactoryGirl.create(:awardunit) }
        visit awardunits_path
      end
      after(:all)  { Awardunit.delete_all }

      it { should have_selector('div.pagination') }

      it "should list each awardunit" do
        Awardunit.paginate(page: 1).each do |awardunit|
          expect(page).to have_selector( 'a', awardunit.name)
        end
      end

    end


    ### Award Unit Edit page

    describe "awardunit edit page" do
        let(:awardunit) { FactoryGirl.create(:awardunit) }

        before do 
            visit edit_awardunit_path(awardunit)
        end

        it { should have_title("Edit #{awardunit.name} | SLNYAA Core") }

    end

    ### Award Unit Show page


    describe "awardunit show page" do
        let(:awardunit) { FactoryGirl.create(:awardunit) }

        before do 
            visit awardunit_path(awardunit)
        end

        it { should have_title("#{awardunit.name} Award Unit | SLNYAA Core") }

    end

2 个答案:

答案 0 :(得分:4)

如果每个数字必须落在3 - 9之间的限制不是真正的限制,那么每次按顺序你都可以获得真正独特的值:

factory :awardunit do
  ...
  sequence(:nyaaid) { |n| "NYAA/N/WP#{ "%04d"%n } }
  ...
end

<强>更新

以下代码将执行您想要的操作,并且只为每个字符生成3-9之间的数字,同时提供唯一值时间。

factory :awardunit do
  ...
  sequence(:nyaaid) { |n| "NYAA/N/WP#{ n.to_s(7).split('').map{|c| "#{c.to_i + 3}" }.join } }
  ...
end

旁注:如果您正在寻找“虚假”数据的一些差异,那么有一个名为Faker的伟大宝石将允许您拥有“真实的”虚假数据。 https://github.com/stympy/faker

答案 1 :(得分:0)

确实如此。您使用此nyaaid生成[1,1,1,1].map!{|x| (3..9).to_a.sample}.join,其中只有大约2400个可能的值。我认为产生重复的机会非常高。

我不知道对该属性的验证有多严格,也许您可​​以使用nyaaidSecureRandom.hex生成sequence(:nyaaid) { |n| "NYAAID#{n}" }。这将允许更多的变化。或者您需要使用以下内容生成有效的nyaaid

def generate_nyaaid
  loop
    nyaaid = [1,1,1,1].map!{|x| (3..9).to_a.sample}.join
    return nyaaid if Awardunit.where(nyaaid: nyaaid).count < 1
  end
end