如何在应用程序记录抽象基类中测试方法



我还没有找到测试ApplicationRecord方法的好方法。

假设我有一个名为 one 的简单方法:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  def one
    1
  end
end

我想测试一下:

describe ApplicationRecord do
  let(:it) { described_class.new }
  it 'works' do
    expect(it.one).to eq 1
  end
end

不出所料,这NotImplementedError: ApplicationRecord is an abstract class and cannot be instantiated.

所以我尝试了在 Rspec 中测试抽象类中的匿名类建议:

let(:it) { Class.new(described_class).new }

这随着TypeError: no implicit conversion of nil into String而死亡,大概是因为记录的表名为零。

谁能建议一种简单、简单的方法来测试ApplicationRecord方法? 希望它不会在我的应用程序中引入对其他类的依赖关系,并且不会在 ActiveRecord 内部中扎根?

这在我们的

测试中一直对我有用:

class TestClass < ApplicationRecord
  def self.load_schema!
    @columns_hash = {}
  end
end
describe ApplicationRecord do
  let(:record) { TestClass.new }
  describe "#saved_new_record?" do
    subject { record.saved_new_record? }
    before { allow(record).to receive(:saved_change_to_id?).and_return(id_changed) }
    context "saved_change_to_id? = true" do
      let(:id_changed) { true }
      it { is_expected.to be true }
    end
    context "saved_change_to_id? = false" do
      let(:id_changed) { false }
      it { is_expected.to be false }
    end
  end
end

它只是阻止类尝试数据库连接来加载表架构。

显然,随着Rails的发展,你可能不得不更新你这样做的方式,但至少它位于一个容易找到的地方。

我更喜欢这个,而不是拥有另一个模块来允许测试。

我建议将这些方法提取到模块(关注)中,而不要理会ApplicationRecord。

module SomeCommonModelMethods
  extend ActiveSupport::Concern
  def one
    1
  end
end
class ApplicationRecord < ActiveRecord::Base
  include SomeCommonModelMethods
  self.abstract_class = true
end
describe SomeCommonModelMethods do
  let(:it) { Class.new { include SomeCommonModelMethods }.new } } 
  it 'works' do
    expect(it.one).to eq 1
  end
end

如果您使用的是 Rspec,则可以创建一个共享示例,然后从从 ApplicationRecord 继承的每个模型的规范中调用它。这将具有在每个模型上测试所有这些行为的缺点,但开销应该相当低,除非您将大量共享行为塞进 ApplicationRecord。

最新更新