2016-03-20 14 views
2

Ich versuche ein paar Tests zu lernen und stolperte über Spott und Stubbing. Ich glaube tatsächlich, dass ich hier den Unterschied machen kann. Ich kann mir keinen Grund vorstellen, warum ich überhaupt spotten sollte. Schauen wir uns das Beispiel-Code von Mocha gem Dokumentation:Warum Mock-Daten beim Testen?

require 'test/unit' 
require 'mocha/test_unit' 

class MiscExampleTest < Test::Unit::TestCase 
    test "mocking_an_instance_method_on_a_real_object" do 
     person = Person.new 
     person.expects(:save).returns(true) 
     assert person.save 

    end 

Ich verstehe nicht, den Grund hinter dieser Zeile:

Ob ich es verwenden oder nicht, der Ausgang ist völlig gleich: die Test besteht. Ich kann fühlen, dass es etwas damit zu tun hat, dem Objekt/der Klasse zu sagen, wie es sich zu verhalten hat, aber wie testen wir, wenn wir dem Objekt zuerst sagen, dass es wahr ist, und dann prüfen, ob es wahr zurückgibt? Es wird immer so sein, wir haben es gesagt. Ist es nicht sinnlos?

+0

Sie haben grundsätzlich recht. Tests werden nur weniger umfangreich, wenn Sie sich verspotten. Der Vorteil von Mocks ist, dass Sie verschiedene Teile Ihrer App isoliert testen können. Außerdem sind bestimmte Funktionen schwer zu testen, so dass Sie sich verspotten können, wenn Sie keine Lust dazu haben. –

Antwort

6

Das Beispiel, das Sie in der Tat scheint nicht gepostet viel Sinn zu machen:

test "mocking_an_instance_method_on_a_real_object" do 
    person = Person.new 
    person.expects(:save).returns(true) 
    assert person.save 
end 

In der Tat der Test nicht Person überhaupt nicht testen, es prüft nur, dass die Schein funktioniert.

Aber Mocking oder Stubbing kann sehr sinnvoll sein: Sie können Teile umgehen, an denen Sie nicht interessiert sind (die nicht im Geltungsbereich sind), um Ihre Testsuite zu beschleunigen, indem Sie keine Daten aus Ihrer Datenbank laden externe Dienste anrufen

Stellen Sie sich folgendes Beispiel: Sie haben eine Methode, die einen externen Zahlungsanbieter Anrufe und können einen Fehler zurück:

def make_payment(user, amount) 
    payment = ExternalPaymentGateway.transfer(company_account, user.account, amount) 
    raise 'payment error' if payment.error? 
end 

diese Methode zu testen, die Sie nicht wollen echte Zahlungen leisten, und Sie wollen nicht Rufen Sie den externen Dienst überhaupt an (weil unnötige API-Anfragen Ihre Testsuite verlangsamen). Stattdessen möchten Sie diesen Dienst komplett stumm machen:

ExternalPaymentGateway.expects(:transfer).returns(true) 
assert_nothing_raised make_payment(user, '$100000') 

ExternalPaymentGateway.expects(:transfer).returns(false) 
assert_raised 'payment_error' do 
    make_payment(user, '$100000') 
end 
+0

AFAICS, das angegebene Beispiel stammt aus Mochas Dokumentation und zeigt rein das Verhalten der Methoden 'expects' und' returns'. In diesem Zusammenhang macht es Sinn (es scheint aus irgendeinem Grund ein allgemeines Idiom in der Testrahmendokumentation zu sein, die Methoden auf diese Weise zu dokumentieren). –

0

Nein, es wird nicht immer wahr zurückgegeben. Beim Testen wird sichergestellt, dass jeder Zoll Ihres Codes wie erwartet ausgeführt wird, nachdem Sie den Code geändert oder seine Umgebung geändert haben. Wenn Sie kürzlich eine neue Datenbank, einen geänderten Host oder eine geänderte Datenbank.yaml installiert haben, wird dieser "Speichern" -Test false zurückgeben. Das sollte dann Flags in Ihrem Kopf auslösen, um nicht zum Master zu gelangen, bis Sie den Datenbankverbindungsfehler behoben haben.

+0

Lesen Sie das Beispiel erneut. Wie geschrieben, ist der ganze Zweck ein triviales Beispiel, das in der Tat immer wieder wahr wird. Es sei denn, Mocha hat natürlich einen Fehler. OP fragt, warum er Mocks/Fälschungen verwenden sollte, nicht ob er Unit-Tests durchführen soll. –

Verwandte Themen