2012-07-01 39 views
1

使用Ruby-1.9.3 ...如何在Ruby中將塊傳遞給assert_raise?

我讀過一些規範的博客文章對塊&特效的主題,但我不明白爲什麼這兩種情況是不同的:

module TestHelpers 
    def bad_arg_helper(&scenario) 

    # this works fine, test passes (without the next line) 
    assert_raise ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters", { Myclass.myfunc "bad" } 

    # even though the exception is correctly raised in myfunc, this assert does not see it and the test fails 
    assert_raise ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters", scenario.call 
    end 
end 

class TestClass < Test::Unit::TestCase 
    include TestHelpers 

    def test_bad_args 
    bad_arg_helper { Myclass.myfunc "bad" } 
    end 
end 

如何將一個塊傳遞給另一個模塊中的測試助手?

+2

嘗試'&scenario',而不是在第二行'scenario.call'。 –

+0

這樣做......我還沒有看到一個例子,其中'&'在參數列表之外使用。爲什麼'method.call'不能在這裏工作?什麼時候在方法體中使用'&'是合適的?請隨時爲信用回答,並在任何情況下,謝謝。 – jordanpg

+0

查看knut的回答:) –

回答

2

請參閱代碼中的三個變種:

require 'test/unit' 
class Myclass 
    def self.myfunc(par) 
    raise ArgumentError unless par.is_a?(Fixnum) 
    end 
end 

module TestHelpers 
    def bad_arg_helper(&scenario) 

    # this works fine, test passes (without the next line) 
    assert_raise(ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters") { Myclass.myfunc "bad" } 

    # even though the exception is correctly raised in myfunc, this assert does not see it and the test fails 
    assert_raise(ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters", &scenario) 
    assert_raise(ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters") { yield } 
    assert_raise(ArgumentError, "wrong type of arguments, pass Fixnum or Range parameters") { scenario.call } 
    end 
end 

class TestClass < Test::Unit::TestCase 
    include TestHelpers 

    def test_bad_args 
    bad_arg_helper { Myclass.myfunc "bad" } 
    end 
end 
+0

很好的例子。如果我正確理解了語義,就可以像引用任何其他變量一樣將一個Proc('&scenario')引用傳遞給一個函數(即在括號內),但實際的塊不能。不過,我不明白爲什麼'scenario.call'可以在大括號內工作。它是否返回塊的返回值? – jordanpg

+0

'scenario.call'調用'scenario'並將結果傳遞給方法。所以如果沒有花括號,你不會返回一個塊,而是場景的結果。用大括號將方塊傳遞給方塊。在Block內部,你可以調用'scenario'。一個問題是大括號的雙重含義:它可以是散列或塊。如果沒有圓括號,紅寶石有問題可以識別,如果你有散列或塊。 – knut