5

StateMachineFactory Girl으로 테스트하는 데 문제가 있습니다. 그것은 공장 소녀가 객체를 초기화하는 방식으로 보입니다.FactoryGirl 및 StateMachine을 사용하여 동적 초기 상태 테스트

내가 누락되었거나 쉽지 않은가?

class Car < ActiveRecord::Base 
    attr_accessor :stolen # This would be an ActiveRecord attribute 

    state_machine :initial => lambda { |object| object.stolen ? :moving : :parked } do 
    state :parked, :moving 
    end 
end 

Factory.define :car do |f| 
end 

그래서, 초기 상태는 stolen 속성을 초기화하는 동안 설정되어 있는지 여부에 따라 달라집니다.

: 공장 소녀 개별적으로의 재 지정을 ( factory_girl/proxy/build.rb 참조)를 설정하기 전에 객체를 초기화하기 때문에

Car.new(:stolen => true) 

## Broadly equivalent to 
car = Car.new do |c| 
    c.attributes = {:stolen => true} 
end 
car.initialize_state # StateMachine calls this at the end of the main initializer 
assert_equal car.state, 'moving' 

그러나,이 흐름이 더 같은 의미 :이 액티브가 초기화의 일부로 속성을 설정하기 때문에, 잘 작동하는 것 같다

Factory(:car, :stolen => true) 

## Broadly equivalent to 
car = Car.new 
car.initialize_state # StateMachine calls this at the end of the main initializer 
car.stolen = true 
assert_equal car.state, 'moving' # Fails, because the car wasn't 'stolen' when the state was initialized 

답변

3

당신은 당신의 공장상의 after_build 콜백을 추가 할 수 있습니다 그러나

Factory.define :car do |c| 
    c.after_build { |car| car.initialize_state } 
end 

, 난 당신이 오 생각하지 않는다 이런 식으로 초기 상태를 설정해야합니다. FactoryGirl처럼 ActiveRecord 객체를 사용하는 것이 일반적입니다 (예 : c = Car.net; c.my_column = 123).

초기 상태가 nil이되도록 허용하는 것이 좋습니다. 그런 다음 활성 레코드 콜백을 사용하여 상태를 원하는 값으로 설정하십시오.

class Car < ActiveRecord::Base 
    attr_accessor :stolen # This would be an ActiveRecord attribute 

    state_machine do 
    state :parked, :moving 
    end 

    before_validation :set_initial_state, :on => :create 

    validates :state, :presence => true 

    private 
    def set_initial_state 
    self.state ||= stolen ? :moving : :parked 
    end 
end 

나는 이것이 당신에게 더 예측 가능한 결과를 줄 것이라고 생각합니다.

한 가지주의 할 점은 아직 상태가 설정되지 않기 때문에 저장되지 않은 자동차 개체 작업이 어려울 수 있다는 것입니다.

0

시도한 결과 님의 답변이 FactoryGirl은이 구문을 허용하지 않으며 after_build 메서드는 ActiveRecord 개체에 없습니다. 이 새로운 구문은 작동해야합니다.

Factory.define 
    factory :car do 
    after(:build) do |car| 
     car.initialize_state 
    end 
    end 
end