views:

322

answers:

1

Update

Answered below. In case the linked site disappears, you can use mocha to stub the initial state and prevent overwriting as in ...

require 'mocha'
class OrderTest < ActiveSupport::TestCase
  def setup
    Order.any_instance.stubs(:set_initial_state)
    @order = Factory(:order, :state => "other_state")
  end

  ...
end

Original Question

I am currently running the Acts As State Machine Rails Plugin (has been a huge time saver, incidentally) and having some challenges using it with Factory Girl (also wonderful).

I want to be able to set the object state when I create the object with Factories. A generalized way of asking this question is "how do you call class methods when creating a object with Factories?"

class Transporter < ActiveRecord::Base
  validates_presence_of :company_name, :on => :update
  acts_as_state_machine :initial => :created, :column => 'status'
  state :created
  state :active
  state :inactive, :after => :inactivate_transporter_activity
end

Factory.define :transporter do |f|
  f.sequence(:company_name) {|n| "transporter_company#{n}"}
end

>> t=Factory(:transporter)
=> <Transporter ... status: "created">
>> t=Factory(:transporter, :status => 'active')
=> <Transporter ... status: "created"> #as expected, changes state back
>> t.activate!
=> true
>> t
=> <Transporter ... status: "active">

I can always call the t.activate! method within every test, but this will make my tests brittle. I'm looking for a way to run this method at Factory creation level or set it within factory.rb.

Thanks...

+2  A: 

You can use a mocking framework (mocha) to override set_initial_state and get the correct state on your object.

>> require 'mocha'
=> []
>> Transporter.any_instance.stubs(:set_initial_state)
=> #<Mocha::Expectation:0x21ee6e4 ...
>> t = Factory(:transporter, :state => "active")
=> #<Transporter ... state: "active">

Idea stolen from here.

Joel Meador
Thanks a bunch. 30 mins of Googling for this answer and I couldn't find it. Doh!Anyway, thanks. Maybe the next person will have an easier time finding it through the StackOverflow SEO.
Kevin Dewalt