7

sto lavorando su Exercise 49 of Learn Ruby the Hard Waycorretta Assert_Raise Unit Testing ed uso di Eccezione Classe

L'esercizio chiede di scrivere un test di unità per ogni funzione prevista. Uno degli elementi che sto testando è se viene sollevata un'eccezione corretta. Si suggerisce di utilizzare assert_raise per questo scopo.

Ecco il codice che sto testando:

class ParserError < Exception 

end 

Pair = Struct.new(:token, :word) 

def peek(word_list) 
    begin 
     word_list.first.token 
    rescue 
     nil 
    end 
end 

def match(word_list, expecting) 
    word = word_list.shift 
    if word.token == expecting 
     word 
    else 
     nil 
    end 
end 

def skip_word(word_list, token) 
    while peek(word_list) == token 
     match(word_list, token) 
    end 
end 

def parse_verb(word_list) 
    skip_word(word_list, :stop) 

    if peek(word_list) == :verb 
     return match(word_list, :verb) 
    else 
     raise ParserError.new("Expected a verb next.") 
    end 
end 

E qui è il test, per la funzione parse_verb:

def test_parse_verb 
    list_one = [Pair.new(:verb, 'go'), Pair.new(:noun, 'king')] 
    assert_equal(parse_verb(list_one), Pair.new(:verb, 'go')) 

    list_two = [Pair.new(:noun, 'player') ,Pair.new(:verb, 'go'), Pair.new(:noun, 'king')] 
    assert_raise(ParserError.new("Expected a verb next.")) {parse_verb(list_two)} 
end 

Quando eseguo il test, non riesce e qui è il messaggio ottengo:

Larson-2:test larson$ ruby test_sentence.rb 
Loaded suite test_sentence 
Started 
.F.. 
Finished in 0.001204 seconds. 

    1) Failure: 
test_parse_verb(SentenceTests) [test_sentence.rb:36]: 
[#<ParserError: Expected a noun or direction next.>] exception expected, not 
Class: <ParserError> 
Message: <"Expected a verb next."> 
---Backtrace--- 
/Users/larson/Ruby/projects/ex48/lib/sentence.rb:45:in `parse_verb' 
test_sentence.rb:36:in `block in test_parse_verb' 
--------------- 

4 tests, 7 assertions, 1 failures, 0 errors, 0 skips 

Test run options: --seed 40627 

sulla base della mia comprensione della funzione assert_raise, questo test deve passare, c'è qualcosa di sbagliato nel modo in cui lo sto usando?

Se qualcuno vuole un codice sorgente completo di tutti i file che sto lavorando con i È disponibile here

risposta

28

assert_raise aspetta una o più classi di eccezione come i suoi parametri, piuttosto che un caso di eccezione desiderata.

Restituisce anche l'eccezione sollevata, quindi se si desidera far valere il messaggio (o qualsiasi altra proprietà), è possibile farlo separatamente. Quindi provare a sostituire:

assert_raise(ParserError.new("Expected a verb next.")) {parse_verb(list_two)} 

con:

exception = assert_raise(ParserError) {parse_verb(list_two)} 
assert_equal("Expected a noun or direction next.", exception.message) 
+0

Grazie per l'aiuto! Questo ha risolto il mio problema. –

2

Per qualche ragione, la risposta di cui sopra non ha funzionato per me (sto usando Rubino 2.0.0).

mi deve avvolgere il nome della classe di errore in una stringa per farlo funzionare:

assert_raise("RuntimeError") { 
    # some code to trigger the error 
}