Ассоциация тестирования Rspec приводит к сбою - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь создать «компоненты» для своего проекта, и каждый компонент относится к одному из четырех типов (Section, Composition, 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 голосов
/ 04 июля 2018

Причина неудачного теста

Но это работает, когда я перемещаю спецификацию из section_spec.rb в component_spec.rb

Местоположение вашего rspec здесь не является причиной сбоя, как мне кажется. То, что вы делаете неправильно, назначая Component экземпляр в вашем section_spec.rb как 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...