Reputation: 1471
I'm creating some tests and I would like to create an array of objects passing different parameters to the constructor, is there a smart way of doing that?
For example, suppose I have this code:
foos = 3.times.map{ Foo.new("a") }
This code would give me an array with 3 foo
's, but all of them initialized with the "a"
parameter.
I would rather have an array where the first one is initialized with "a"
, the second with "b"
and the third with "c"
, like it would if did this:
foos = [Foo.new("a"),Foo.new("b"),Foo.new("c")]
Is there a smarter way of doing this?
Upvotes: 1
Views: 264
Reputation: 1848
Going a bit deeper on your question, I'm going to suggest you two libraries: Factory Girl and Faker. None is Rails nor Rspec specific.
With Factory Girl you can define factories to create test data and with Faker you can associate randomized data to your factories.
I'm suggesting these two libraries because creating test data for simple use cases is easy, but it starts to get very complicated when you have more complex relationships between objects.
Here's an example to get you started:
class Foo < Struct.new(:bar)
end
FactoryGirl.define do
factory :foo do
bar Faker::Number.digit
end
end
FactoryGirl.build_list(:foo, 3)
=> [#<struct Foo bar=3>, #<struct Foo bar=2>, #<struct Foo bar=7>]
FactoryGirl.build(:foo)
=> #<struct Foo bar=5>
FactoryGirl.build(:foo, bar: 2)
=> #<struct Foo bar=2>
Here are more examples on how powerful Factory Girl is. Just remember that you need to use the build*
methods instead of create*
methods, because create*
methods also call on save
to persist the data when using it with a persistence layer.
Upvotes: 3
Reputation: 9497
Just to offer an alternative:
arr = ['a', 'b', 'c']
Array.new(arr.size) { |i| Foo.new arr[i] }
#=>
#[#<Foo:0x000000025db798 @arg="a">,
# #<Foo:0x000000025db748 @arg="b">,
# #<Foo:0x000000025db6d0 @arg="c">]
Upvotes: 2
Reputation: 30056
Try this one
%w(a b c).map { |s| Foo.new(s) }
In case you don't know
%w(a b c)
is a shorter way to say
["a", "b", "c"]
Upvotes: 3