ruby-on-rails - 使用 FactoryGirl 和 StateMachine 测试动态初始状态

标签 ruby-on-rails testing activerecord factory-bot state-machine

我在使用 Factory Girl 测试 StateMachine 时遇到了一些问题。看起来这取决于 Factory Girl 初始化对象的方式。

我是不是遗漏了什么,或者这不是应该的那么简单?

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 属性。这似乎工作正常,因为 ActiveRecord 将属性设置为其初始化程序的一部分:

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 Girl 在单独设置其覆盖之前初始化对象(参见 factory_girl/proxy/build.rb ),这意味着流程更像是:

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

最佳答案

您可以在您的工厂中添加一个 after_build 回调:

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

但是,我认为您不应该依赖于以这种方式设置您的初始状态。像 FactoryGirl 那样使用 ActiveRecord 对象是很常见的(即通过调用 c = Car.net; c.my_column = 123)。

我建议您允许您的初始状态为零。然后使用事件记录回调将状态设置为所需的值。

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

我认为这会给您带来更可预测的结果。

需要注意的是,使用未保存的 Car 对象会很困难,因为状态尚未设置。

关于ruby-on-rails - 使用 FactoryGirl 和 StateMachine 测试动态初始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5728584/

相关文章:

java - 测试程序java

android - 如何使用Android API以编程方式启动Instrumentation项目? (指定测试类(class)!)

javascript - 使用不显眼的 Javascript 插入包含 Rails RESTful URL 的元素?

ruby-on-rails - Ruby 中的文本格式(用于装箱单)

ruby-on-rails - ruby - uniq 有什么区别!和独特的

ruby-on-rails - 在 Rails 用户模型中设置 default_address

ruby-on-rails - 参数丢失或值为空 : user

ruby-on-rails - rails : render text gives missingtemplate error

android - 使用 Robolectric 测试带有 intent extras 的服务的启动?

ruby-on-rails - 按带分页的关联模型排序