Ruby Test :: nil SimpleDelegator的UnitTest

时间:2014-10-03 20:05:13

标签: ruby

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

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 预计无零。

1次测试,1次断言,1次失败,0次错误,0次跳过

咦? assert_nil是否检查NilClass?在这种情况下,这将失败。

2 个答案:

答案 0 :(得分:1)

test / unit的#assert_nil方法正在调用#nil?找出对象是否为零。问题是,Fred的祖先链中的Object定义了#nil?。由于SimpleDelegator只委托丢失方法,#nil?正在返回Fred的结果,而不是委托人。

要解决这个问题,你可以定义nil吗?并亲自转发给代理人:

def nil?
  __getobj__.nil?
end

这个答案也适用于minitest。

答案 1 :(得分:0)

“嗯?断言是否检查NilClass?在这种情况下会失败。”

1.8.7在Test::Unit::Assertions中但是对于&gt; 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))

是Floats(在你的情况下没有)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_strpretty_inspect字符串,exp_commentact_comment为对象类。从技术上讲,这条消息将会读取

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

然后使用===比较它们并将其传递给assert

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

这是文档

assert_nil

assert_equal