class 方法规范 - 保留顺序和 returns ActiveRecord 关系

Spec for class method - preserving order and returns an ActiveRecord relation

Rails 很新,目前正在学习如何处理 class 方法、范围和规范... 最初这是作为模型中的一个范围编写的,但它看起来有点臃肿,所以我把它取出来并变成了 class 方法,如下所示:

class OrderedByIds

  scope :for_ids_with_order, lambda { |ids|
    order = sanitize_sql_array(
      ["position((',' || id::text || ',') in ?)", ids.join(',') + ',']
    )
    where(id: ids).order(order)
  }

end

# 用法:

 OrderedByIds.for_ids_with_order([1, 3, 2])

对此 class 方法进行单元测试的最佳方法是什么?

您不能真正对其进行单元测试,因为它与数据库紧密耦合。 所以 Rails 模型测试并不是真正的单元测试。

因此,您可以对其进行测试,这非常简单。 (我假设您使用的是 FactoryBot and your rspec is Aggregating failures

let!(:order) { create(:order) }
let!(:other_order) { create(:order) }

specify do
   expect(describe_class.for_ids_with_order([order.id])).to eq [order]
   expect(describe_class.for_ids_with_order([other_order.id])).to eq [other_order]
end

然后,您可以执行另一个测试顺序的上下文:我将创建 3 个或更多项目,具有指定的位置并做出上述期望,但您期望的是具有特定顺序的几个项目的数组(我不是 100% 确定 "position((',' || id::text || ',') in ?)" 在那里做什么,因此没有例子。但这应该让你继续)。

顺便说一句。如果它是示波器,我会以完全相同的方式对其进行测试。

编辑:我错过了关于重新调整 AR 关系的部分。

expect(describe_class.for_ids_with_order([order.id])).to be_a(ActiveRecord::Relation)