Factory Girl对于功能测试非常有用,但是有一个恼人的属性使得在单元测试中使用起来稍微困难一些,我不想依赖测试数据库。我经常使用Factory.build
创建一个工厂,然后我可以使用flexmock传递或分配到ActiveRecord.find
来电:
require 'test_helper'
require 'flexmock'
class SomeMixinTest < ActiveSupport::TestCase
include FlexMock::TestCase
def setup
@foo = Factory.build(:foo, :id => 123,
:bar => Factory.build(:bar, :id => 456,
:baz => Factory.build(:baz, :id => 789)
)
)
flexmock Foo, :find => @foo
end
def test_find_by_reverse_id
assert_equal @foo, Foo.find_by_reverse_id(321)
end
end
这种模式非常好,因为它不关心数据库的存在,并且运行速度比实际持久化对象要快得多。但是,必须手动构建关联对象有点烦人。如果不这样做,则build
调用实际上会在数据库中创建关联对象 ,就像您使用了create
一样。
assert_equal [], Foo.all
foo = Factory.build :foo # build my associations too, please
assert_equal [], Foo.all # look Ma, no mocks!
assert_equal [], Bar.all # <=== ASSERTION FAILED
assert_equal [], Baz.all
这至少可以说是非直观的,当我测试一些需要与mixin很好地合作的类时,会导致实际问题。我希望能够做到这一点:
KLASSES_UNDER_TEST = [Foo, Bar, Baz]
def test_find_by_reverse_id
KLASSES_UNDER_TEST.each do |klass|
objects = (123..456).map do |id|
Factory.build klass.to_s.downcase.to_sym, :id => id
end
flexmock klass, :all => objects
objects.each do |object|
assert_equal object, klass.find_by_reverse_id(object.id.to_s.reverse), "#{klass} #{object.id}"
end
end
但这会产生令人讨厌的副作用,即在数据库中创建333 Bar
和666 Baz
es(“Baz”听起来有点像恶魔的昵称,所以可能是合适的)这个测试比冬天上流的糖蜜慢。
我想创建一个这样的辅助方法:
def setup_mocks(klass)
klass_sym = klass.to_s.downcase.to_sym
objects = (123..456).map{|id|
associated_objects = Hash[
Factory.associations(klass_sym).map do |association|
[ association, setup_mocks(association, 1) ]
end
]
Factory.build klass_sym, associated_objects
end
flexmock klass, :all => objects
objects
end
那么,Factory.associations
之类的东西是否存在?
答案 0 :(得分:0)
我没有对此进行过测试,但是看一下这个来源似乎应该有效:
FactoryGirl.find(:factory_name).associations