问题 如何在RSpec中检查Nil的变化


所以我很确定这会起作用......

expect { file.send(:on_io) {} }.to change{
  file.io.class
}.from( NilClass ).to( File )

但它失败了这条消息......

result should have initially been NilClass, but was NilClass

胡?

首先,为什么这会以失败告终?其次,我通常知道你可以检查nil be_nil 通过使用 nil? 方法。是否有一些特殊的方法来做到这一点 from().to() 在RSpec?


3646
2017-11-30 23:21


起源



答案:


这应该工作:

expect { file.send(:on_io) {} }.to change{
  file.io
}.from(NilClass).to(File)

rspec将使用 === 比较中的值 from 和 to。但 === 不是可交换的,当在类上调用时,它将检查它的参数是否是类的实例。所以:

NilClass === NilClass
#=> false

因为NilClass不是NilClass的实例。另一方面,

NilClass === nil
#=> true
nil === nil
#=> true
nil === NilClass
#=> false

因为nil是NilClass的一个实例,所以nil等于nil,但是nil不等于NilClass。

您也可以这样编写测试:

expect { file.send(:on_io) {} }.to change{
  file.io
}.from(nil).to(File)

我觉得这是最具可读性的。


12
2017-12-01 00:58



如果 nil === NilClass 返回false,不会 file.io === File 也返回false(假设 file.io 是一个实例 File)? - webdesserts
但测试将是 File === file.io,这就是重点:) - Jean-Louis Giordano
啊,好吧,参数 to 和 from 将其与返回值进行比较,而不是相反。说得通。谢谢你解释一切顺利! - webdesserts


答案:


这应该工作:

expect { file.send(:on_io) {} }.to change{
  file.io
}.from(NilClass).to(File)

rspec将使用 === 比较中的值 from 和 to。但 === 不是可交换的,当在类上调用时,它将检查它的参数是否是类的实例。所以:

NilClass === NilClass
#=> false

因为NilClass不是NilClass的实例。另一方面,

NilClass === nil
#=> true
nil === nil
#=> true
nil === NilClass
#=> false

因为nil是NilClass的一个实例,所以nil等于nil,但是nil不等于NilClass。

您也可以这样编写测试:

expect { file.send(:on_io) {} }.to change{
  file.io
}.from(nil).to(File)

我觉得这是最具可读性的。


12
2017-12-01 00:58



如果 nil === NilClass 返回false,不会 file.io === File 也返回false(假设 file.io 是一个实例 File)? - webdesserts
但测试将是 File === file.io,这就是重点:) - Jean-Louis Giordano
啊,好吧,参数 to 和 from 将其与返回值进行比较,而不是相反。说得通。谢谢你解释一切顺利! - webdesserts