2012-06-03 4 views
22

Voglio verificare se una funzione richiama correttamente altre funzioni con Ruby minitest, ma non riesco a trovare un valore corretto per assert da doc.Come affermare che determinati metodi vengono chiamati con il framework minitest di Ruby?

Il codice sorgente
class SomeClass 
    def invoke_function(name) 
    name == "right" ? right() : wrong() 
    end 

    def right 
    #... 
    end 

    def wrong 
    #... 
    end 
end 
Il codice di prova:
describe SomeClass do 
    it "should invoke right function" do 
    # assert right() is called 
    end 

    it "should invoke other function" do 
    # assert wrong() is called 
    end 
end 

risposta

21

Con Minitest si utilizza expect metodo per impostare l'aspettativa di un metodo per essere chiamato su un oggetto fittizio in questo modo

obj = MiniTest::Mock.new 
obj.expect :right 

Se si desidera impostare le aspettative con parametri e valori di ritorno, quindi:

obj.expect :right, return_value, parameters 

E per l'oggetto concreto in questo modo:

obj = SomeClass.new 
assert_send([obj, :right, *parameters]) 
+2

Per la versione oggetto concreto, c'è 'must_send' per quando si utilizza' Minitest/spec' – Frost

+0

Dimmi se mi manca qualcosa ma penso che la risposta di @ jing-li qui sotto sia corretta nel menzionare che "assert_send" non è appropriato qui. L'OP vuole testare che 'right' è chiamato quando viene chiamato' invoke_function'. Inoltre, 'obj.verify' è necessario per assicurare che' right' venga chiamato sull'oggetto mock nella prima parte di questa risposta. Per chiunque stia leggendo questo, assicurati che i tuoi test falliscano prima di farli passare. – monozok

+0

Penso che l'utilizzo di assert_send non sia una scelta sicura. secondo i documenti: http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html#method-i-assert_send –

9

Minitest ha una speciale .expect :call per verificare se qualche metodo viene chiamato.

describe SomeClass do 
    it "should invoke right function" do 
    mocked_method = MiniTest::Mock.new 
    mocked_method.expect :call, return_value, [] 
    some_instance = SomeClass.new 
    some_instance.stub :right, mocked_method do 
     some_instance.invoke_function("right") 
    end 
    mocked_method.verify 
    end 
end 

Sfortunatamente questa funzione non è documentata molto bene. L'ho trovato da qui: https://github.com/seattlerb/minitest/issues/216

0

In base all'esempio fornito, non esiste un'altra classe di delegati e si desidera assicurarsi che il metodo venga chiamato correttamente dalla stessa classe. Poi sotto frammento di codice dovrebbe funzionare:

class SomeTest < Minitest::Test 
    def setup 
    @obj = SomeClass.new 
    end 

    def test_right_method_is_called 
    @obj.stub :right, true do 
     @obj.stub :wrong, false do 
     assert(@obj.invoke_function('right')) 
     end 
    end 
    end 

    def test_wrong_method_is_called 
    @obj.stub :right, false do 
     @obj.stub :wrong, true do 
     assert(@obj.invoke_function('other')) 
     end 
    end 
    end 
end 

L'idea è di stub [method_expect_to_be_called] restituendo un semplice vero valore, e nel blocco stub affermare che è davvero di essere chiamato e restituendo il valore vero . Per stub l'altro metodo inaspettato serve solo per assicurarsi che non venga chiamato.

Nota: assert_send non funzionerà correttamente. Si prega di fare riferimento a official doc.

In realtà, al di sotto dichiarazione passerà, ma non significa che funzioni come previsto:

assert_send([obj, :invoke_function, 'right']) 
# it's just calling invoke_function method, but not verifying any method is being called