2009-11-04 6 views
5

Ich verwende TestUnit und möchte feststellen, ob eine Funktion aufgerufen wird. Ich habe eine Methode in einer Klasse namens Person, die ich gesetzt ‚BEFORE_UPDATE‘ genannt werden:Testen Sie, ob eine Funktion in einem Ruby on Rails Unit-Test aufgerufen wird

def geocode_if_location_info_changed 
    if location_info_changed? 
     spawn do 
     res = geocode 
     end 
    end 
    end 

Dann habe ich einen Komponententest:

def test_geocode_if_location_info_changed 
    p = create_test_person 
    p.address = "11974 Thurloe Drive" 
    p.city = "Baltimore" 
    p.region = Region.find_by_name("Maryland") 
    p.zip_code = "21093" 
    lat1 = p.lat 
    lng1 = p.lng 

    # this should invoke the active record hook 
    # after_update :geocode_if_location_info_changed 
    p.save 
    lat2 = p.lat 
    lng2 = p.lng 
    assert_not_nil lat2 
    assert_not_nil lng2 
    assert lat1 != lat2 
    assert lng1 != lng2 

    p.address = "4533 Falls Road" 
    p.city = "Baltimore" 
    p.region = Region.find_by_name("Maryland") 
    p.zip_code = "21209" 

    # this should invoke the active record hook 
    # after_update :geocode_if_location_info_changed 
    p.save 

    lat3 = p.lat 
    lng3 = p.lng 
    assert_not_nil lat3 
    assert_not_nil lng3 
    assert lat2 != lat3 
    assert lng2 != lng3 
end 

Wie kann ich, dass die „Geocodierung“ Verfahren gewährleisten hieß? Dies ist wichtiger für den Fall, in dem ich sicherstellen möchte, dass es nicht aufgerufen wird, wenn sich die Standortinformationen nicht geändert haben.

Danke!

Antwort

6

Verwenden Sie Mokka. Dies testet die Logik Ihres Filters:

def test_spawn_if_loc_changed 
    // set up omitted 
    p.save! 
    p.loc = new_value 
    p.expects(:spawn).times(1) 
    p.save! 
end 

def test_no_spawn_if_no_data_changed 
    // set up omitted 
    p.save! 
    p.other_attribute = new_value 
    p.expects(:spawn).times(0) 
    p.save! 
end 
+0

Ich stimme dieser Antwort zu, obwohl ich denke, dass Sie 'p.expects (: geocode_if_location_info_changed) .times (1)' wollen. Ich bin OK mit Mokka hier zu verwenden. Ein Vorher-Filter scheint meiner Meinung nach ziemlich nah an einem Kollaborateur zu sein. –

+0

Ich habe versucht, die Logik des vor-Filter zu testen, und * spawn * ist das erste, was in der if. Wenn Sie nur den Aufruf des Vorher-Filters testen, testen Sie nur, dass der "before_filter" vorhanden war und dass rails funktioniert ... das ist gut, aber es schien, als würden wir versuchen, die Logik innerhalb des Filters zu erreichen. – ndp

+0

Guter Punkt - ich kann diesen Winkel sehen. –

1

Was Sie brauchen, sind Mock-Objekte (siehe Mockobjects und Mocks aren't stubs für weitere allgemeine Informationen). RSpec hat support for them, und es gibt andere eigenständige Bibliotheken (zum Beispiel Mocha), die Ihnen helfen sollten, wenn Sie nicht zu RSpec wechseln müssen.

+0

Was soll ich hier vortäuschen? Mein Personenobjekt ist das getestete System und laut Martin Fowlers Artikel sollten Mocks für Kollaborateure verwendet werden. – Tony