7

的使用,我對Exercise 49 of Learn Ruby the Hard Way正確Assert_Raise單元測試和異常類

工作的練習要求寫出所提供的每項功能的單元測試。我正在測試的項目之一是如果提出適當的例外。建議我們使用assert_raise來達到這個目的。

這裏是我的測試代碼:

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 

這裏是考驗,對於功能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 

當我運行測試,它失敗,這裏是消息我得到:

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 

根據我對assert_raise函數的理解,這個測試應該通過,我使用它的方式有什麼問題嗎?

如果有人想所有文件的完整的源代碼,我有我的工作是提供here

回答

28

assert_raise預計一個或多個異常類作爲它的參數,而不是必需的例外的一個實例。

它也返回引發的異常,所以如果你想斷言消息(或任何其他屬性),你可以單獨做。因此,嘗試更換:

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

有:

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

感謝您的幫助!這解決了我的問題。 –

2

出於某種原因,上面給出的我沒有工作了答案(我使用Ruby 2.0.0)。

我有一個字符串來包裝錯誤的類名,它的工作:

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