Rspec断言两个SQL查询相同

时间:2019-01-16 13:26:38

标签: ruby-on-rails ruby rspec

我正在使用rpsec断言某个方法会生成预期的查询:

describe '.customers' do

    let(:segment) { create(:segment) }

    let!(:rule1) do
      Rule.create!(segment: segment, filter_key: 'generic',
                   attr_name: 'first_name', operator: '=', values: ['john'])
    end

    let!(:rule2) do
      Rule.create!(segment: segment, filter_key: 'generic',
                   attr_name: 'orders_count', operator: '>=', values: ['3'])
    end

    let(:actual_query) { segment.customers.to_sql }
    let(:expected_query) do
      Customer
        .where('first_name = john')
        .where('orders_count >= 3')
        .to_sql
    end

    it 'applies all the rules scopes to customer' do
      expect(actual_query).to eq(expected_query)
    end

end

通常会通过,问题是有时(出于某种原因)其中一个sql查询中的where子句会重新排序,因为to_sql实际上是要执行的查询的字符串,有时会失败:

  

失败/错误:期望(actual_query)。到eq(expected_query)

 expected: "SELECT \"customers\".* FROM \"customers\" WHERE (orders_count >= '3') AND (first_name = 'john')"

    got: "SELECT \"customers\".* FROM \"customers\" WHERE (first_name = 'john') AND (orders_count >= '3')"
 (compared using ==)

当它们在执行方面实际上相同时。 关于其他如何断言两个查询的想法是相同的,而不必在执行后添加测试客户来比较查询

1 个答案:

答案 0 :(得分:1)

它似乎与segment.customers中规则的排序有关。由于它们是一个接一个地创建的,因此它们在created_at中的时间戳可能是相同的。

我将对它们进行明确排序,并添加规范中支持它的数据,例如:

let!(:rule1) do
  Rule.create!(segment: segment, filter_key: 'generic',
               attr_name: 'first_name', operator: '=', values: ['john'],
               created_at: 2.days.ago)
end

let!(:rule2) do
  Rule.create!(segment: segment, filter_key: 'generic',
               attr_name: 'orders_count', operator: '>=', values: ['3'],
               created_at: 1.day.ago)
end