Rafael Costa
Rafael Costa

Reputation: 1471

How to map with different parameters - ruby

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

Answers (3)

Gaston
Gaston

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

Sagar Pandya
Sagar Pandya

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

Ursus
Ursus

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

Related Questions