6

我在尝试为我在项目中定义的一些对象和关联创建工厂时遇到了麻烦。我有一种循环类型的关联,其中一个对象与其他两个随后连接在一起的对象关联。

+--------------+           +-------------+
|              |           |             |
| TestCase     +---------> | TestDataGrid|
|              |           |             |
+------+-------+           +------+------+
       |                          |
       |                          |
       |                          |
       v                          v
+--------------+           +--------------+
|              |           |              |
|              |           |              |
| TestVariable |           | TestDataSet  |
|              |           |              |
+------+-------+           +------+-------+
       |                          |
       |                          |
       |                          |
       |                          |
       |     +---------------+    |
       |     |               |    |
       |     |               |    |
       +---> | TestDataValue |<---+
             |               |
             +---------------+

class TestCase < ActiveRecord::Base
  has_many :test_variables, dependent: :destroy
  has_many :test_data_grids
  #...omitted code...
end

class TestVariable < ActiveRecord::Base
  belongs_to :test_case
  has_many :test_data_values
  #...omitted code...
end

class TestDataValue < ActiveRecord::Base
  belongs_to :test_variable
  belongs_to :test_data_set
  #...omitted code...
end

class TestDataSet < ActiveRecord::Base
  belongs_to :test_data_grid
  has_many :test_data_values
  #...omitted code...
end

class TestDataGrid < ActiveRecord::Base
  belongs_to :test_case
  has_many :test_data_sets
  #...omitted code...
end

基本上,该关联在 TestCase 中分裂并在 TestDataValue 中再次加入,我如何创建一个使用相同对象打开和关闭圆圈的工厂?

4

3 回答 3

0

这未经测试,但是:

FactoryGirl.define do

 factory :test_data_value do
  test_data_set
  test_variable
  # attributes
 end

 factory :test_data_set do
  test_data_grid
  # attributes
 end

 factory :test_variable do
  test_case
  # attributes
 end

 factory :test_case do
  # attributes
 end

 factory :test_data_grid do
  test_case
  # attributes
 end
end

然后在规格中:

@test_data_value = FactoryGirl.create(:test_data_value)

@test_variable = @test_data_value.test_variable
@test_data_set = @test_data_value.test_data_set
于 2012-09-07T17:04:56.937 回答
0

我的建议是不要在工厂中设置它,而是在测试本身中设置它。

工厂文件(感谢 @veritas1)

FactoryGirl.define do

  factory :test_data_value do
    # attributes
  end

  factory :test_data_set do
    # attributes
  end

  factory :test_variable do
    # attributes
  end

  factory :test_case do
    # attributes
  end

  factory :test_data_grid do
    # attributes
  end
end

测试文件

@test_case = FactoryGirl.create(:test_case)
@test_data_grid = FactoryGirl.create(:test_case)
@test_variable = FactoryGirl.create(:test_case)
@test_data_set = FactoryGirl.create(:test_case)
@test_data_value = FactoryGirl.create(:test_case)
@test_case.test_data_grids << @test_data_grid
@test_case.test_variables << @test_variable
@test_data_grid.test_data_set << @test_data_set
@test_variable.test_data_values << @test_data_value
@test_data_set.test_data_values << @test_data_value

我知道这可能有点糟糕,但听起来像是这样做的方式。不过,作为一个想法,如果您在测试中遇到困难,这通常表明您将在跟踪过程中遇到困难,您应该重新设计 API。我看不到另一种方法,但您可能能够了解该领域的知识。

于 2012-09-11T14:39:13.063 回答
0

您可以手动执行此操作:

test_case = FactoryGirl.build(:test_case)

test = FactoryGirl.build(:test_data_value,
  :test_variable => FactoryGirl.build(:test_variable,
     :test_case => test_case
  ),
  :test_data_set => FactoryGirl.build(:test_data_set,
    :test_data_grid => FactoryGirl.build(:test_data_grid,
       :test_case => test_case
    )
  )
)

test.test_variable.test_case == test.test_data_set.test_data_grid.test_case
# => true

或者写一些辅助工厂:

FactoryGirl.define do
  factory :test_data_value do
    ignore do
      test_case nil
      test_data_grid nil
    end

    test_variable do
      build :test_variable,
        :test_case => test_case 
                      || test_data_grid.try(:test_case) 
                      || build(:test_case)
    end

    test_data_set do
      build :test_data_set, :test_data_grid => test_data_grid || (
        build :test_data_grid, :test_case => test_case || build(:test_case)
      )
    end
  end
end

测试用例作为共同祖先:

test = FactoryGirl.create :test_data_value, 
  :test_case => FactoryGirl.build(:test_case)

test.test_variable.test_case == test.test_data_set.test_data_grid.test_case
# => true

作为共同祖先的测试用例和每个实例的相同 test_data_grid :

test_data_grid = FactoryGirl.build :test_data_grid, 
  :test_case => FactoryGirl.build(:test_case)

test = FactoryGirl.create :test_data_value, 
  :test_data_grid => test_data_grid

test.test_variable.test_case == test.test_data_set.test_data_grid.test_case
# => true
于 2012-09-16T20:36:36.233 回答