2012-10-18 42 views
1

使用Mocha以簡單的代碼以意想不到的方式轉向。你能解釋發生了什麼問題嗎?摩卡:爲什麼我不能存根#caller方法?

require 'test-unit' 
require 'mocha' 

class A 
    def m 
    caller.first 
    end 
end 

因此,使用這種簡單的類,我們可以得到最新的來電者:

A.new.m #=> "(irb):32:in `irb_binding'" (for example) 

但是,如果我想存根caller通話,事情出錯。

a = A.new 
a.stubs(:caller) 

Mocha::ExpectationError: unexpected invocation: #<A:0x6aac20>.caller() 

我的猜測是檢查出Mocha來源,但以後我會做到這一點;)


  • 紅寶石1.9.3p194
  • 測試單元2.5.0,2.4.8
  • 摩卡0.12.6

回答

1

這是一個局部解釋,但我希望它仍然有用。

正如您所建議的,瞭解這裏發生了什麼的方法是檢查摩卡來源。我認爲問題的關鍵在於Expectation類,它在創建存根時使用,makes use of the caller method itself

解決方法是使用alias_method

class A 
    alias_method :my_caller, :caller # allow caller to be stubbed 

    def m 
    my_caller.first 
    end 
end 

a = A.new 
a.stubs(:my_caller) 
+0

謝謝。所以要注意,現在基本上沒有辦法在'Mocha'中扼殺'caller'。 –

+0

似乎是這樣。我認爲這是由於Mocha想要使用更好的樣式'a.stubs(:method)'而不是像'stub(a::method)'這意味着設置存根的代碼運行於你的對象的上下文,所以如果你試圖在存根創建過程中使用任何方法存根,即使你真的只想爲你的對象存留行爲,你也會遇到這種問題。顯然,選擇的摩卡語法總體上更好,它只是導致這樣的邊緣情況的問題。 – mikej

+0

看起來像是我的問題。由於'Kernel'包含在'Object'中,'Mocha'可以在'Kernel'上調用'caller'或者有點像這樣。 –

0

m打電話給caller。所以caller.first將永遠是調用m的行,這可能是無用的。可能你想要的是caller[1],而不是caller.first(或caller[0])。

+0

基本上沒有。這個想法是有能力存根'調用者'。無論如何,感謝您的關注。 –