Rspec утверждают, что два sql запроса одинаковы - PullRequest
0 голосов
/ 16 января 2019

Я использую 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

Обычно это проходит, дело в том, что иногда (по какой-то причине) предложения where в одном из запросов sql переупорядочиваются так, поскольку to_sql на самом деле является строкой запроса, который нужно выполнить, иногда это не удается говоря:

Сбой / Ошибка: ожидаемо (актуальный_запрос). К уравнению (ожидаемый_запрос)

 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 голосов
/ 16 января 2019

Похоже, это связано с упорядочением ваших правил в segment.customers. Поскольку они создаются один за другим, возможно, что их временные метки в created_at совпадают.

Я бы упорядочил их в явном виде и добавил бы данные, которые поддерживают это, в спецификации, например ::100100

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...