Фиктивная модель ActiveRecord в RSpec - PullRequest
3 голосов
/ 12 февраля 2020

У меня есть модуль, который добавляет некоторые функции в ActiveRecord. Чтобы протестировать эту модель, я хотел бы создать фиктивную модель в RSpe c, чтобы я не зависел от своих производственных моделей:

describe MyModule do
  before do
    ActiveRecord::Base.connection.create_table :articles, force: true do |t|
      t.string(:name)
    end
  end

  after do
    ActiveRecord::Base.connection.drop_table(:articles, if_exists: true)
  end

  class Article < ApplicationRecord
    belongs_to :author
  end

  class Author < ApplicationRecord
    has_many :articles
  end

  it "does some stuff" do
    ...
  end
end

Проблема в том, что Рубокоп жалуется на RSpec/LeakyConstantDeclaration и предлагает извлечь фиксированные классы в let:

  let(:article_class) do
    Class.new(ApplicationRecord) do
      has_many :comments
    end
  end
  let(:author_class) do
    Class.new(ApplicationRecord) do
      has_many :articles
    end
  end

  before do
    stub_const("Article", article_class)
    stub_const("Author", author_class)
  end

Это прекрасно работает, когда я запускаю один тест. Но когда я запускаю несколько тестов, они проваливаются, потому что отсутствуют статьи и / или авторы Похоже, что прошлые тесты влияют на другие тесты.

Похоже, что ActiveRecord не совсем подходит для таких определений моделей. Поэтому я хотел бы знать, есть ли лучший способ определить фиктивные модели в RSpe c?

1 Ответ

0 голосов
/ 13 февраля 2020

Вы можете извлечь общий контекст

RSpec.shared_context 'with test tables  and models' do 
  before do
    ActiveRecord::Base.connection.create_table :articles, force: true do |t|
      t.string(:name)
    end

    stub_const("Article", article_class)
    stub_const("Author", author_class)
  end

  after do
    ActiveRecord::Base.connection.drop_table(:articles, if_exists: true)
  end

  let(:article_class) do
    Class.new(ApplicationRecord) do
      has_many :comments
    end
  end

  let(:author_class) do
    Class.new(ApplicationRecord) do
      has_many :articles
    end
  end

и включить его в каждый тест, в котором он необходим.

describe MyModule do
  include_context 'with test tables  and models' 

  # your examples here
end
...