Faker menghasilkan data duplikat saat digunakan di factory_girl


86

Saya mencoba mengisi beberapa data palsu ke pabrik menggunakan permata Faker:

Factory.define :user do |user|
  user.first_name Faker::Name::first_name
  user.last_name Faker::Name::last_name
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Namun sementara saya berharap ini menghasilkan pengguna yang memiliki first_name dan last_names yang berbeda, masing-masing sama:

>> Factory(:user)
=> #<User id: 16, email: "user7@blow.com", created_at: "2011-03-18 18:29:33",     
updated_at: "2011-03-18 18:29:33", first_name: "Bailey", last_name: "Durgan">
>> Factory(:user)
=> #<User id: 17, email: "user8@blow.com", created_at: "2011-03-18 18:29:39", 
updated_at: "2011-03-18 18:29:39", first_name: "Bailey", last_name: "Durgan">

Bagaimana saya bisa mendapatkan permata Faker untuk membuat nama baru untuk setiap pengguna dan tidak hanya menggunakan kembali yang asli?


1
Hanya bidikan dalam kegelapan, tetapi apakah Anda sudah mencoba menggunakan sesuatu seperti itu user.sequence(:first_name} {|n| Faker::Name::first_name}? FactoryGirl kemungkinan hanya mengevaluasi panggilan Faker Anda saat memuat "perlengkapan" Anda. Menggunakan sequence param,&blockmetode ini seharusnya mencegah hal itu.
Steven

Jawaban:


156
Factory.define :user do |user|
  user.first_name { Faker::Name::first_name }
  user.last_name { Faker::Name::last_name }
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Coba letakkan tanda kurung di sekitar penipu. lihat tautan ini


8
Saya sangat menyukai stackoverflow - terima kasih Will, Anda telah menyelamatkan daging saya
Peter Nixey

Terima kasih, ini memperbaiki masalah saya!
Jeruk13

5
Mengapa mengapa mengapa? Apa yang terjadi disini?
jordanpg


10
Sayangnya ini tidak selalu berhasil. Ini pada dasarnya hanya mendapatkan objek faker acak baru, namun karena RNG, masih ada kemungkinan gagal.
Michael Lynch

46

Perhatikan bahwa Faker mungkin masih memberikan data duplikat karena terbatasnya jumlah data palsu yang tersedia.

Untuk tujuan pengujian sederhana dan untuk mendapatkan validasi keunikan, saya telah menggunakan yang berikut ini:

sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}

3
Jawaban ini membutuhkan lebih banyak suara positif. Ini mungkin terjadi ketika pengujian Anda membuat banyak contoh.
Enrico Carlesso

Yup, saya setuju dengan Enrico. +1
karlingen

Ide bagus, tetapi menambahkan tanda kurung dapat menghentikan sisanya jika Anda menggunakan nama depan dan nama belakang untuk membuat email, atau Anda memiliki validasi pada formatnya (tidak tahu nama apa pun yang memiliki tanda kurung: P).
Cyril Duchon-Doris

18

Demi menjaga jawaban yang benar, ini dia translokasi dari blog, saya tidak menghargai jawabannya.

Jika Anda menggunakan kode di bawah ini, faker tidak akan menghasilkan nama unik

Factory.define :user do |u|
  u.first_name Faker::Name.first_name
  u.last_name Faker::Name.last_name
end

Namun menempatkan kawat gigi keriting di sekitar pembuat palsu membuatnya berhasil!

Factory.define :user do |u|
  u.first_name { Faker::Name.first_name }
  u.last_name { Faker::Name.last_name }
end

Untuk menjelaskan alasannya, contoh pertama menghasilkan nama yang sama. Ini hanya mengevaluasi sekali. Contoh kedua mengevaluasi setiap kali pabrik digunakan.

Ini karena {} pemberian evaluasi malas. Pada dasarnya mereka menyediakan proc / lambda dengan panggilan Faker sebagai nilai kembalian mereka.


Terima kasih telah memposting ini. Saya tidak tahu mengapa Faker tidak dapat menghasilkan data acak dan sepertinya setiap contoh yang saya temukan menunjukkan cara menggunakan pengurutan yang menurut saya aneh. Saya ingin menggunakan Faker sehingga setiap record acak, tidak diurutkan. Hanya menambahkan kawat gigi di sekitar panggilan Faker saya menyelesaikan masalah. Sederhana dan elegan!
Blimey85

5

Alternatif (kurang efisien) untuk menggunakan urutan ketika Anda memiliki validasi keunikan pada atribut adalah dengan memeriksa apakah nilai yang diusulkan sudah ada dan terus mencoba yang baru sampai unik:

FactoryGirl.define do
  factory :company do
    name do
      loop do
        possible_name = Faker::Company.name
        break possible_name unless Company.exists?(name: possible_name)
      end
    end
  end
end
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.