2017-03-04 52 views
1

我有一個非常奇怪的問題,使用Minitest將方法調度到錯誤的類。Ruby方法調用錯誤(頂級模塊)類

我正在幫助維護dnsruby庫(https://github.com/alexdalitz/dnsruby),並且我們有一個間歇性失敗的特定測試(https://github.com/alexdalitz/dnsruby/blob/master/test/tc_resolv.rb#L56)。

通過設置在撬斷點,我發現,當它出現故障它是使用在內部紅寶石Resolv類而不是在代碼中指定的Dnsruby::Resolvgetname方法。無論::ResolvDnsruby::Resolv似乎指向Ruby的內部Resolv類:當測試在其自身(ruby test/tc_resolv.rb)運行不發生

[1] pry(#<TestResolv>)> ::Resolv.object_id => 70320518250220 [2] pry(#<TestResolv>)> Dnsruby::Resolv.object_id => 70320518250220

錯誤。當與其他測試結合使用(使用ruby test/ts_online.rb並修改其運行的測試文件列表)時,它經常失敗,但有時不會。我發現似乎與失敗相關的唯一因素是運行的測試代碼的數量;運行的測試越多,失敗的可能性就越大。

如果測試成功,::Resolv甚至沒有定義:

[1] pry(#<TestResolv>)> ::Resolv.object_id NameError: uninitialized constant Resolv

我搜索我們的代碼庫require 'resolv'但沒有找到它。也許我們正在使用的另一個庫需要它。儘管如此,不應該在Dnsruby::ResolvDnsruby::指定我們定製的Resolv類?

我們該如何解決這個問題?

+0

我會假設,一旦你發現誰需要resolv,更容易發現那裏正在發生的事情。你有沒有嘗試在resolv.rb中提出一個錯誤,以便你能看到它的需求? – phoet

+0

有趣的想法。我這樣做,發現了一個需要它的測試文件。但是,當我僅測試該文件和測試文件時,錯誤未發生; :: Resolv和Dnsruby :: Resolv都可用,但指向正確的(即不同的)類,並通過了測試。所以問題不在於需要'resolv',而在於某種程度上Dnsruby :: Resolv被覆蓋指向:: Resolv in _some_ cases。 –

+0

你可以使用'TracePoint'或'set_trace_func'來檢查它是否被某個類覆蓋。 – phoet

回答

0

該問題已通過刪除頂層的include Dnsruby得到解決,該頂層應該不存在。 (感謝Ruby社區成員https://github.com/matt-glover發現此問題!)

更多詳細信息請參閱Github問題https://github.com/alexdalitz/dnsruby/issues/112,修復程序位於https://github.com/alexdalitz/dnsruby/pull/121/files的拉取請求中。

讓我困惑的一件事......我本來期望的是,包括導致Dnsruby :: Resolv類被拉入頂層,但似乎發生了相反的情況。