2014-10-03 97 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