2014-10-03 138 views
1
require 'delegate' 

class Fred < SimpleDelegator 

    def initialize(s) 
    super 
    end 
end 

puts Fred.new([]) == []  # ==> true 
puts Fred.new({}) == {}  # ==> true 
puts Fred.new(nil) == nil # ==> true 

Ruby測試::的單元測試零SimpleDelegator

require 'test/unit' 
class FredTest < Test::Unit::TestCase 

    def test_nilliness 
    assert_nil Fred.new(nil) 
    end 
end 

回報...... 運行測試:

˚F

成品測試中0.000501s,1996.0080測試/秒, 1996.0080斷言/ s。

1)失敗: test_nilliness:20 預計nil爲零。

1測試中,1個斷言,1次失敗,0失誤,0跳過

咦? assert_nil是否檢查NilClass?這在這種情況下會失敗。

+0

由於你沒有 指定一個紅寶石版本下面的2個答案應該照顧這個對你的依賴。 – engineersmnky 2014-10-03 21:00:46

回答

1

測試/單元的#assert_nil方法正在調用#nil?找出對象是否爲零。問題在於Fred的祖先鏈中的Object定義了#nil ?.由於SimpleDelegator只委託缺少的方法,#nil?將結果返回給Fred,而不是委託人。

要解決這個問題,你可以定義零?並自己轉發給代表:

def nil? 
    __getobj__.nil? 
end 

此答案同樣適用於minitest。

+0

你可以指點我在哪裏調用'#nil?',因爲我沒有在Docs中看到這個,但是你的方法確實有效。這是如何工作的? – engineersmnky 2014-10-03 20:44:35

+0

@engineersmnky https://github.com/seattlerb/minitest/blob/2c269ed351d8583da075cdfc6bfc3542ca1c5fce/lib/minitest/assertions.rb#L236 – 2014-10-03 20:45:17

+0

謝謝。我只查看'Test :: Unit :: Assertions'而不是'MiniTest :: Assertions'。 +1 – engineersmnky 2014-10-03 20:47:17

0

「Huh?assert_nil checking for NilClass?that would fail in this case。」

1.8.7在Test::Unit::Assertions但爲> 1.8.7請看MiniTest::Assertions並參見@ WayneConrad的回答/評論,因爲這是正確的。

不完全它檢查類彼此,因爲一切都失敗,但字符串表示是相同的。如果你看一下它使用assert_equal源,檢查以下內容:

pretty_inspect串相同(在你的情況是)if exp_str == act_str

Fred.new(nil).pretty_inspect.chomp #=> "nil" 
    nil.pretty_inspect.chomp   #=> "nil" 

的對象都是字符串或兩個正則表達式(在你的情況無)if (exp.is_a?(String) && act.is_a?(String)) ||(exp.is_a?(Regexp) && act.is_a?(Regexp))

的對象都花車(你的情況沒有)elsif exp.is_a?(Float) && act.is_a?(Float)

的對象了時間(在你的情況下,沒有)elsif exp.is_a?(Time) && act.is_a?(Time)

是類不平等的(在你的情況是),則elsif exp.class != act.class

Fred.new(nil).class #=> Fred 
    nil.class   #=> NilClass 

消息是否等於"<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}"

其中exp_stract_str將是pretty_inspect字符串和exp_commentact_comment是對象類。因此從技術上講這條消息將讀取

"<nil>NilClass expected but was\n<nil>Fred" 

然後使用===對它們進行比較並傳遞到assert

nil === Fred.new(nil) #=> false 

這裏是文檔

assert_nil

assert_equal