Rspec 如何测试ApplicationRecord抽象基类中的方法?

Rspec 如何测试ApplicationRecord抽象基类中的方法?,rspec,rails-activerecord,rspec-rails,ruby-on-rails-5,Rspec,Rails Activerecord,Rspec Rails,Ruby On Rails 5,我还没有找到测试ApplicationRecord方法的好方法 假设我有一个名为one的简单方法: class ApplicationRecord < ActiveRecord::Base self.abstract_class = true def one 1 end end 不出所料,NotImplementedError:ApplicationRecord是一个抽象类,无法实例化。 所以我尝试了匿名课堂建议: 这将随着TypeError而消失:没有将nil隐式

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

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

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def one
    1
  end
end
不出所料,
NotImplementedError:ApplicationRecord是一个抽象类,无法实例化。

所以我尝试了匿名课堂建议:

这将随着
TypeError而消失:没有将nil隐式转换为字符串
,可能是因为记录的表名是nil


有人能推荐一种测试ApplicationRecord方法的简单方法吗?希望它不会在我的应用程序中引入对其他类的依赖关系,也不会在ActiveRecord内部扎根?

我建议将这些方法提取到模块(关注点)中,而不要使用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
模块方法
扩展ActiveSupport::关注点
def一号
1.
结束
结束
类ApplicationRecord
这在我们的测试中对我很有效:

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
class TestClass
它只是防止类尝试数据库连接来加载表架构

很明显,随着Rails的移动,您可能需要更新这样做的方式,但至少它位于一个容易找到的地方


我更喜欢使用这个模块,而不是使用另一个模块来进行测试。

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

是的!就我个人而言,我避免担心(我认为在这个问题上有一些很好的争论)。但是,我同意远离ActiveRecord上的
abstract\u类?这感觉就像是在扭曲我的应用程序的源代码,以弥补语言/库的限制。我仍然希望有人能建议如何测试ApplicationRecord类本身,但感谢您提出的非常好的建议!ApplicationRecord是Rails 5中的标准。为什么会有人回避呢?
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
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