我还没有找到测试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。