2016-04-06 9 views
3

Ich habe eine benutzerdefinierte SQL-Abfrage erstellt und ich möchte eine Unit-Tests erstellen, um zu demonstrieren, dass es funktioniert. Ich habe es in SQLDeveloper getestet und es funktioniert so, wie ich es in meiner Testdatenbank haben möchte, aber ich möchte einen Komponententest für diejenigen hinterlassen, die diesen Code später pflegen müssen.So testen Sie eine Methode, die eine SQL-Abfrage ausführt

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 

Mein Gedanke war, vier Rechnungen zu erstellen, von denen drei nicht die oben genannten Kriterien und ein Treffen, das tut. Wo ich feststecke, ist, wie man überprüft, dass die Abfrage nur eine Antwort zurückgibt. Wie kann ich testen, dass eine Zeile der Abfrage ausgegeben wird?

Klärung ich & Reisen mit factory auf die Erstellung dieser Rechnungen wurde die Absicht, die Modelle zu füllen. Wird das noch funktionieren?

+0

Im Allgemeinen sollten Komponententests nicht von externen Diensten abhängig sein. Ein typischer Komponententest würde die Antwort aus der Testdatenbank verspotten und testen, dass die Verarbeitung der zurückgegebenen Daten ordnungsgemäß erfolgt. Der Grund dafür ist, dass nach dem Schreiben eines Komponententests, der von dieser Datenbank abhängt, die Komponententests jedes Mal geändert werden müssen, wenn Sie die Datenbankimplementierung ändern. Das ist kein Unit Test, es ist ein Integrationstest. TLDR: Du kannst das machen, aber es ist eine schlechte Idee. Weitere Informationen finden Sie hier: http://StackOverflow.com/Questions/10752/what-is-the-difference-between-integration-and-unit-tests – nhouser9

+0

Ich sehe nicht, warum Unit-Tests nicht mit einer Datenbank sprechen können. Das Ändern der Db-Implementierung ist nicht wirklich ein Problem, da es wahrscheinlich nicht passieren wird, und wenn dies der Fall ist, würde dieser Test mit der Datenbank verworfen werden. –

+0

@BSeven Wenn Komponententests beginnen, mit externen Diensten zu sprechen, handelt es sich laut Definition nicht um Komponententests. Sie sind Integrationstests, die separat gepflegt werden sollten. – nhouser9

Antwort

1

Wickeln Sie diese Methode in eine Klasse ein.

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 

In Ihrem Test

report = MerchantReport.for_not_pressed_the_service_rendered_button 

FWIW, ich glaube nicht, Anfragen wie Berichte etwas mit Rechnungen oder anderen Modellen zu tun haben, und in ihrer eigenen Klasse gehört.

Ja, Sie können 4 Rechnungen in Ihrem Setup erstellen. Sie können auch einen separaten Test für jede Bedingung erstellen, die Sie testen möchten. Zum Beispiel können Sie einen Test für das Datum haben (departure_date < SYSDATE). Das kann besser lesbar sein als ein Test für alle Bedingungen.

+0

Dann ein Test wie Assertion wie 'assert_equal 1, report.count'? – CheeseFry

+1

Ich würde auch für den spezifischen Datensatz testen: 'assert_equal valid_invoice, report.first'. –

Verwandte Themen