2016-04-06 6 views
3

Я сделал собственный SQL-запрос, и я хочу создать модульные тесты, чтобы продемонстрировать, что он работает. Я протестировал его в SQLDeveloper, и он работает так, как я хочу, в моей тестовой базе данных, но я хочу оставить единичный тест для тех, кто должен поддерживать этот код позже.Как протестировать метод, выполняющий SQL-запрос

def report_of_merchants_who_have_not_pressed_the_service_rendered_button 
    sql = "SELECT MIN(departure_date), ch_invoice.invoice_id 
    FROM ch_invoice 
    INNER JOIN ch_trip 
    ON ch_invoice.invoice_id = ch_trip.invoice_id 
    WHERE departure_date < SYSDATE 
    AND service_rendered = 0 
    AND paid = 1 
    Group By ch_invoice.invoice_id" 

    report = ActiveRecord::Base.connection.exec_query(sql) 
    render json: report 
    end 

Моя мысль заключалась в том, чтобы создать четыре счета-фактуры, три из которых не соответствуют вышеприведенным критериям, и тот, который делает. Там, где я застрял, как проверить, что запрос возвращает только один ответ. Как проверить, что выходит одна строка запроса?

Разъяснение Я собирался на создание этих счетов-фактур & поездки с FactoryGirl для заполнения модели. Будет ли это работать?

+0

В целом, модульные тесты не должны зависеть от внешних служб. Типичный единичный тест будет извращать ответ из тестовой базы данных и проверять правильность обработки возвращенных данных. Причина в том, что после того, как вы напишете единичный тест, который зависит от этой базы данных, модульные тесты нужно будет менять каждый раз, когда вы измените реализацию своей базы данных. Это не модульный тест, это интеграционный тест. TLDR: Вы можете это сделать, но это плохая идея. Дополнительная информация здесь: http://stackoverflow.com/questions/10752/what-is-the-difference-between-integration-and-unit-tests – nhouser9

+0

Я не понимаю, почему модульные тесты не могут разговаривать с базой данных. Изменение реализации db на самом деле не является проблемой, потому что это вряд ли произойдет, и если это произойдет, то этот тест будет выброшен с помощью базы данных. –

+0

@ Даже потому, что, когда модульные тесты начинают говорить с внешними службами, они не являются модульными тестами по определению. Это интеграционные тесты, которые следует поддерживать отдельно. – nhouser9

ответ

1

Оберните этот метод в классе.

class MerchantReport 
    class << self 
    def for_not_pressed_the_service_rendered_button 
     sql = "SELECT MIN(departure_date), ch_invoice.invoice_id 
     ....  
     ActiveRecord::Base.connection.exec_query(sql) 
    end 

В тесте,

report = MerchantReport.for_not_pressed_the_service_rendered_button 

FWIW, я не думаю, что запросы, как отчеты имеют ничего общего с счетами-фактурами или другими моделями, и принадлежит в своем собственном классе.

Да, вы можете создать 4 счета в своей настройке. Кроме того, вы можете создать отдельный тест для каждого условия, которое вы хотите проверить. Например, вы можете провести один тест на дату (departure_date < SYSDATE). Это может быть более читаемым, чем одно испытание для всех условий.

+0

Затем тест вроде утверждения 'assert_equal 1, report.count'? – CheeseFry

+1

Я бы также протестировал конкретную запись: 'assert_equal valid_invoice, report.first'. –

Смежные вопросы