1
Factory Girl對功能測試非常有用,但有一個令人討厭的屬性,使它在單元測試中稍微難以使用,我不想依賴測試數據庫。我經常使用Factory.build
使用創建一個工廠,然後我就可以繞過或分配到ActiveRecord.find
電話:是否有可能向Factory Girl詢問某工廠有哪些關聯?
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的討厭的副作用(「巴茲」確實聲音有點像一個惡魔的暱稱,所以也許這就是接頭)在數據庫中,使這個測試比在冬天上坡的糖蜜慢。
我想創建一個輔助方法是這樣的:
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
存在?