FactoryGirl factory with Trait(s) that returns a Hash with stringed keys
Asked Answered
D

2

2

I'm trying to use FactoryGirl to build a Hash that returns something like this:

 => {"3"=>"1", "6"=>"Word"}

I'm getting close but not 100% there yet...

The first factory definition i tried looked like this:

factory :faqtory, class: Hash do |f|
  f.ignore do
    fake_word Faker::Lorem.word
  end

  f.sequence(1.to_s) { |n| n }
  f.send(2.to_s,  fake_word.to_s.capitalize)

  initialize_with { attributes.stringify_keys }
end

Unfortunately this doesn't work:

1.9.3p448 :001 > FactoryGirl.build :faqtory
ArgumentError: Trait not registered: fake_word

After that didn't work i assumed the call to fake_word needed to be in a block but that makes no difference.

Any suggestions?

Denitadenitrate answered 17/12, 2013 at 21:25 Comment(0)
D
3

Ignored attributes are defined as methods that you can use from other attributes. When referring to them, you need to define the dependent attributes using a block:

factory :faqtory, class: Hash do |f|
  f.ignore do
    fake_word { Faker::Lorem.word }
  end

  f.sequence(1.to_s) { |n| n }
  f.send(2.to_s) { fake_word.to_s.capitalize }

  initialize_with { attributes.stringify_keys }
end

Defining an attribute without a block only works for literal values like 1 or "hello".

Update

As mentioned in the comments, you probably want fake_word to use a block as well.

Daemon answered 17/12, 2013 at 22:8 Comment(3)
Thank you for this. It's SUPER close, but unfortunately not a working solution. Each factory object built has the same value for key "2".. Same output as i pasted for @vimsha pastie.org/8559316 . I am sure this has to do with "lazy attributes" ( github.com/thoughtbot/factory_girl/blob/master/…) but not sure how to implement a solution.Denitadenitrate
Ah got it! Line 3 should be: fake_word { Faker::Lorem.word }. If you update the answer, i will select as correctDenitadenitrate
Yes, if you want a different word each time, you'll want a block there, too. I updated the answer.Daemon
A
0

Try this.

  factory :faqtory, class: Hash do |f|
    fake_word = Faker::Lorem.word

    f.sequence(1.to_s) { |n| n }
    f.send(2.to_s,  fake_word.to_s.capitalize)

    initialize_with { attributes.stringify_keys }
  end
Acrimony answered 17/12, 2013 at 21:50 Comment(1)
I have tried this and it sorta works. All factory objects you build using this will have the same attributes… example: pastie.org/8559316 (I would expect that the fake_word should be changing)Denitadenitrate

© 2022 - 2024 — McMap. All rights reserved.