Ruby on rails 如何测试复合Rails模型范围?

Ruby on rails 如何测试复合Rails模型范围?,ruby-on-rails,unit-testing,testing,rspec,integration-testing,Ruby On Rails,Unit Testing,Testing,Rspec,Integration Testing,考虑以下模型: class Model < ActiveRecord::Base scope :a, -> () { where(a: 1) } scope :b, -> () { where(b: 1) } scope :a_or_b, -> () { a.or(b) } end 但是感觉就像我在重新测试.a和.b上的.a\u或

考虑以下模型:

class Model < ActiveRecord::Base
  scope :a,       -> () { where(a: 1) }
  scope :b,       -> () { where(b: 1) }
  scope :a_or_b,  -> () { a.or(b) }
end
但是感觉就像我在重新测试
.a
.b
上的
.a\u或
测试 如果我再创作一次,再加上另一个范围,它会越来越大

处理这个问题的明智方法是什么


另外:这是单元测试还是集成测试?

这是一个困难的测试。我要说的是,你必须找到一个亚里士多德式的,介于全面覆盖和规范可读性之间的平均值。测试影响作用域行为的所有可能状态组合可能是不合理的

此外,它不是真正的单元测试,因为它与DB层耦合

我的做法是:

不要测试简单的作用域(例如示例中的
a
b
),请相信AR经过了良好的测试,将您的作用域名称弄清楚并保留它

在更复杂的范围中,您可以反转编写测试的方式: 创建一次样本,然后为不同的范围定义期望值(并使样本名称非常清晰,就像您已经做的那样)

这将稍微减小规范的大小,并且更容易阅读此类规范。但是如果你想对每一个范围都有全面的覆盖,它仍然会增加规格大小

RSpec.description Model do
描述“范围”是什么
让我来!(:with_a_0_和_b_0){create(:model,a:0,b:0)}
让我来!(:with_a_0_和_b_1){create(:model,a:0,b:1)}
让我来!(:with_a_1_和_b_0){create(:model,a:1,b:0)}
让我来!(:with_a_1_和_b_1){create(:model,a:1,b:1)}
它{expect(描述为_class.a。)包含(带有_a_1和_b_1)。和包含(带有_a_1和_b_1)}
它{expect(描述为_class.a)。not_包括(带有_a_0_和_b_0)}
#你明白了吗
为了让这更具可读性,我建议创建一个

RSpec.describe Model do
  describe "scopes" do
    describe ".a" do
      subject { Model.a }
      let!(:with_a_0) { create(:model, a: 0) }
      let!(:with_a_1) { create(:model, a: 1) }

      it { should_not include(with_a_0) }
      it { should     include(with_a_1) }
    end

    describe ".b" do
      subject { Model.b }
      let!(:with_b_0) { create(:model, b: 0) }
      let!(:with_b_1) { create(:model, b: 1) }

      it { should_not include(with_b_0) }
      it { should     include(with_b_1) }
    end

    describe ".a_or_b" do
      subject { Model.a_or_b }
      let!(:with_a_0_and_b_0) { create(:model, a: 0, b: 0) }
      let!(:with_a_0_and_b_1) { create(:model, a: 0, b: 1) }
      let!(:with_a_1_and_b_0) { create(:model, a: 1, b: 0) }
      let!(:with_a_1_and_b_1) { create(:model, a: 1, b: 1) }

      it { should_not include(with_a_0_and_b_0) }
      it { should     include(with_a_0_and_b_1) }
      it { should     include(with_a_1_and_b_0) }
      it { should     include(with_a_1_and_b_1) }
    end
  end
end
是吗 预期(描述为a类) 。检索(使用_a_1_和_b_0,使用_a_1_和_b_1) 。而不是检索(使用_a_0_和_b_0,使用_a_0_和_b_1) 结束
非常感谢您的回答,@Grzegorz!我正试着按照你的建议去做!很乐意提供帮助,如果您有任何后续行动,请随时在评论中ping我。RSpec和测试是我最喜欢的话题:)@rogi