RSpec:如何编写一个需要特定输出但不关心方法的测试?

2024-03-29

我正在尝试了解测试驱动设计,特别是 RSpec。但我在使用 RSpec 书中的一些示例时遇到了麻烦。

在书中,我们测试 $STDOUT 上的输出,如下所示:

output = double('output')
game = Game.new
output.should_receive(:puts).with('Welcome to Codebreaker!')
game.start()

嗯,这确实有效。但我到底为什么要关心 Game 对象是否使用 put() 方法呢?如果我将其更改为 print(),它真的会破坏测试吗?而且,更重要的是,这是否违背了 TDD 的原则之一——我应该测试方法的作用(设计)而不是方法的作用(实现)?

有什么方法可以编写一个测试来测试 $STDOUT 上最终的内容,而不查看什么方法将其放在那里?


创建一个能够写出状态的显示类。

您的生产代码将使用此显示对象,因此您可以自由更改写入 STDOUT 的方式。当您的测试依赖于抽象时,该逻辑将只有一个位置。

例如:

output = stub('output')
game = Game.new(output)
output.should_receive(:display).with('Welcome to Codebreaker!')
game.start()

虽然您的生产代码将包含诸如

class Output
  def display(message)
    # puts or whatever internally used here. You only need to change this here.
  end
end

我将通过执行以下操作来使此测试通过:

def start
  @output.display('Welcome to Codebreaker!')
end

这里的生产代码并不关心输出如何显示。现在抽象已经到位,它可以是任何形式的显示。

上述所有理论都与语言无关,并且很有效。您仍然模拟您不拥有的东西,例如第三方代码,但您仍在测试您是否通过抽象来执行手头的工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RSpec:如何编写一个需要特定输出但不关心方法的测试? 的相关文章

随机推荐