RSpec 中的虚拟 ActiveRecord 模型

23t*_*tux 5 rspec ruby-on-rails

我有一个模块可以向 ActiveRecord 添加一些功能。为了测试这个模型,我想在 RSpec 中创建一个虚拟模型,这样我就可以独立于我的生产模型:

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
Run Code Online (Sandbox Code Playgroud)

问题是,Rubocop 抱怨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
Run Code Online (Sandbox Code Playgroud)

当我运行单个测试时,这非常有效。但是,当我运行多个测试时,它们会失败,因为缺少文章和/或作者。过去的测试似乎会影响其他测试。

ActiveRecord 似乎不能很好地处理这种模型定义。所以我想知道是否有更好的方法在RSpec中定义虚拟模型?

Grz*_*orz -1

您可以提取共享上下文

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
Run Code Online (Sandbox Code Playgroud)

并将其包含在每个需要它的测试中。

describe MyModule do
  include_context 'with test tables  and models' 

  # your examples here
end
Run Code Online (Sandbox Code Playgroud)