Можно ли спросить Factory Girl, какие ассоциации имеет данный завод? - PullRequest
1 голос
/ 11 апреля 2011

Factory Girl невероятно полезен для функционального тестирования, но имеет одно раздражающее свойство, которое немного усложняет его использование в модульных тестах, где я не хочу полагаться на тестовую базу данных.Я часто использую Factory.build для создания фабрики, которую затем могу передать или назначить на ActiveRecord.find вызов, используя flexmock :

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

Это не- Интуитивно понятный, если не сказать больше, и вызывает реальную проблему, когда я тестирую несколько классов, которые должны хорошо играть с миксином.Я хочу быть в состоянии сделать это:

  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 эс ("Баз" действительно звучит как прозвище демонатак что, возможно, это уместно) в базе данных, что делает этот тест медленнее, чем патока, текущая в гору зимой.

Я хотел бы создать вспомогательный метод, подобный этому:

  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?

1 Ответ

0 голосов
/ 19 мая 2011

Я не проверял это, но, глядя на источник, кажется, что-то вроде этого должно работать:

FactoryGirl.find(:factory_name).associations
...