我正在努力
Exercise 49 of Learn Ruby the Hard Way
练习要求为所提供的每个功能编写单元测试.我正在测试的一个项目是,是否引发了适当的异常.建议我们使用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'),'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函数的理解,这个测试应该通过,我使用它的方式有什么问题吗?
解决方法
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)