Rspec 模型关联测试不适用于模型子类

Rspec Model Association Test not working on model subclass

class Proofreader < Role

  has_many :proofreading_jobs,   :class_name => 'ProofreadingJob',   :foreign_key => 'proofreader_id'

end

class ProofreadingJob < ApplicationRecord

  belongs_to :proofreader, class_name: 'Role', foreign_key: :proofreader_id, optional: true
  belongs_to :client,      class_name: 'Role', foreign_key: :client_id
  end

class Role < ApplicationRecord

  belongs_to :user

end

proofreaders factory:

    FactoryBot.define do
      factory :proofreader do
        type { 'Proofreader'}
        hourly_rate { 15 }
        association :user, factory: :employee_user

        factory :proofreader_with_work_events do

          after :create do |proofreader|
            create(:user_event, :recurring_mwf, user: proofreader.user)
          end

        end
      end
    end

spec/model_roles/proofreader_spec.rb

RSpec.describe 'Proofreader', type: :model do

  describe "Associations" do
    it { should have_many(:proofreading_jobs) }
  end

end

测试失败:

Failure/Error: it { should have_many(:proofreading_jobs) }
       expected Associations to respond to `has_many?`

显然 class ProofreadingJob 与那里有关联。我如何编写此测试才能通过?

首先,您必须定义一个主题 - 您的测试将与之交互的对象。

可以是这样的:

describe "Associations" do
  expect(ProofreadingJob.new).to be_valid # ProofreadingJob.new is subject here
end

当你对主题有所了解后,你可以测试联想。可以是这样的:

RSpec.describe ProofreadingJob, type: :model do
  it { should have_many(:proofreading_jobs) }
end

这里的主题由 ProofreadingJob, type: :model 行的 Rspec 定义。请注意,ProofreadingJob 不是字符串,而是实际的模型名称 (class),因此 Rspec 将知道如何根据该模型制作主题。

要使用这种语法,您必须添加 shoulda-matchers