I have a address model where I have validation if country, city, state and postal code has a valid combination.
address_factory
city { Faker::Address.city }
state { Faker::Address.state }
postcode { Faker::Address.postcode }
country { ISO3166::Country.countries.sample.alpha2 }
As each field id being populated randomly, validation get failed. I don't want to hard code these values. I have a comma separated file with valid combinations.
CodePudding user response:
this worked for me. api/spec/support/address_helper.rb
module AddressHelper
module_function
def csv_data
file_path = Rails.root.join("spec", "fixtures", "australian_addresses.csv")
csv_text = File.read(file_path)
CSV.parse(csv_text, headers: true)
end
def random_location
size = csv_data.length - 1
index = Random.rand(0..size)
csv_data[index].to_hash
end
end
RSpec.configure do |config|
config.include AddressHelper
end
spec/factories/address_factory.rb
factory :address do
transient do
location { AddressHelper.random_location }
end
name { Faker::Name.name }
city { location["city"] }
state { location["state"] }
postcode { location.values.first }
country { location["country"] }
street_1 { Faker::Address.street_address }
email { Faker::Internet.email }
end
CodePudding user response:
The factory is to create model instances for testing, and the field values should be valid by default when an instance is created. This is the reason we ask for validations, because the value validity depends on them.
Your current solution has a problem that the csv file is read each time when the instance is created, and it may slow down tests. It's not necessary to pick an valid value from the whole list unless you have a reason. (If you want to test validations, you should write test cases for them, not in the factory).
A more practical way is just preparing some valid values and random pick them in factory, for example: city: { ['city1', 'city2', 'city3'].sample }
. It should be sufficient for most use cases.