2011-04-11 70 views
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存在?

回答

0

我沒有測試這一點,但看着似乎這樣的事情應該工作來源:

FactoryGirl.find(:factory_name).associations 
相關問題