【问题标题】:Dummy ActiveRecord model in RSpecRSpec 中的虚拟 ActiveRecord 模型
【发布时间】:2020-02-12 08:58:13
【问题描述】:

我有一个向 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

问题是,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

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

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

【问题讨论】:

  • article_class 是否在 stub_const("Article", article_class) 之前被访问?
  • 它真的必须是一个模型还是可以使用一个双类?查看测试和被测对象真的很有帮助。
  • 对不起,完全错过了这些 cmets:它是为一个提供 ActiveRecord 的即时加载的库,所以需要数据库中的真实对象,而类 double 是不够的
  • 我知道这是一个旧的,因为我正在研究它,不妨给我的 2 美分。您是如何在测试中引用ArticleAuthor 的?一旦你实例化了匿名类(也存根类名)并将它们分配给let,你就可以通过定义的let开始引用,例如。 author_class.newauthor_class.create 而不是 Article.create

标签: ruby-on-rails rspec


【解决方案1】:

您可以提取shared context

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

【讨论】:

  • 这并不能解决 ActiveRecord 在处理匿名类时行为怪异的问题
猜你喜欢
  • 1970-01-01
  • 2021-08-27
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多