Rspec测试关联导致失败

时间:2018-07-03 21:53:04

标签: ruby-on-rails rspec

我正在尝试为我的项目创建“组件”,并且每个组件都属于四种类型(部分,组合,LearningIntentions或EssentialQuestion)之一。一个节是一个组件,可以包含多个组件,但是一个节不能包含一个节。

但是,当我运行自己的规范时,出现错误Expected Component to have a has_many association called components (no association called components)。但是,当我将规范从section_spec.rb移到component_spec.rb时,它可以工作。这是怎么回事?

component.rb(模型):

class Component < ApplicationRecord

  # == Constants =============================
  TYPES = %w( Section Composition LearningIntentions EssentialQuestion )

  # == Associations ==========================
  belongs_to :project
  belongs_to :section,
    class_name: 'Component',
    foreign_key: :section_id,
    optional: true

  # # == Validations ===========================
  validates :type,
    presence: true,
    inclusion: { in: TYPES }

end

section.rb(模型):

class Section < Component

  # == Associations ==========================
  has_many :components,
    class_name: 'Component',
    foreign_key: :section_id

  # == Validations ===========================
  validates :section_id, presence: false

end

section_spec.rb:

RSpec.describe Section, type: :model do
  subject! { build(:component, :section) }

  # == Associations ==========================
  it { is_expected.to have_many(:components) }

end

1 个答案:

答案 0 :(得分:0)

测试失败的原因

  

但是当我将规范从section_spec.rb移到component_spec.rb

时,它可以工作

在我看来,rspec的位置并不是此处失败的原因。您做错了什么,就是在您的 section_spec.rb 中将一个Component实例分配为subject,因此,它希望关联:components出现在该Component实例。

修复失败的测试

将代码更改为下面的代码,并查看其是否有效:

RSpec.describe Section, type: :model do
  subject { build(:section) }
  it { is_expected.to have_many(:components) }
end

在工厂中使用特征

如果您要构建一个分配了其组件的Section实例,请定义一个trait并按以下方式使用它:

# Factory
factory :section do
  trait :with_components do
    after(:build) do |s|
      # Modify this to create components of different types if you want to
      s.components = [create(:component)]
    end
  end
end

# Rspec
subject { build(:section, :with_components) }

更多的事物

在您的Component模型中,这种关联看起来很混乱:

belongs_to :section,
  class_name: 'Component',
  foreign_key: :section_id,
  optional: true
  • 您确定要将一个Component实例链接到另一个Component实例吗?

  • 同时,您想使用外键:section_id而不是常规的component_id吗?

您的应用程序中已经有一个模型Section。这可能会引起混乱。见下文:

component = Component.first
component.section
 => #<Component id: 10001>      # I would expect it to be a `Section` instance looking at the association name
相关问题