factory girl passing arguments to model definition on build/create factory girl passing arguments to model definition on build/create ruby ruby

factory girl passing arguments to model definition on build/create


FactoryGirl requires you to define factory first. Let's say in a file spec/factories/messages.rb:

FactoryGirl.define do  factory :message do    bundle_id 1    order_id 2    ...etc...  endend

After this you'll be able to invoke factory build create like this:

FactoryGirl.build(:message)  # => bundle_id == 1, order_id == 2FactoryGirl.build(:message, order_id: 3) # => bundle_id == 1, order_id == 3

However, there is one problem in your particular case. FactoryGirl's default builders operate on top of ActiveRecord-alike interface. It sets defined attributes through setters, not through a hash of attrs passed to the model constructor:

m = Message.newm.bundle_id = 1m.order_id  = 2

So you have to create a custom constructor to work with the interface of your model (which doesn't conform to ActiveRecord-alike model) and register it in your factory definition. See factory girl docs for details.

Let me show you an example of doing so. Sorry I didn't test it but it should give you a clue:

FactoryGirl.define do  factory :message do    ignore do      # need to make all attributes transient to avoid FactoryGirl calling setters after object initialization      bundle_id 1      order_id 2    end    initialize_with do      new(payload: attributes)    end  endend


It's because you have a constructor with mandatory arguments. You have a few options;

1) Make the argument non-mandatory (although this would mean you're changing your code to suit your tests - naughty!)

def initialize(message = nil)

2) Use the "initialize_with" syntax in your factory;

describe Message do  it 'should save the payload' do    payload = {:payload=>{:order_id=>138251, :order_number=>"AW116554416"},   :concern=>"order_create"}    message = FactoryGirl.build(:message, {:payload=>{:order_id=>138251, :order_number=>"AW116554416"}, :concern=>"order_create"})    message.event.should == "order_create"  end  initialize_with { new(message) }end