在RSpec期间抑制STDOUT,但不抑制Pry

时间:2018-04-10 06:06:06

标签: ruby rspec pry

我正在测试一个生成器,它向STDOUT输出大量内容。我想压制这个,并且有很多答案。

但我仍然希望能够使用撬。现在,如果我需要撬入测试状态,我必须禁用抑制。

我正在使用此代码。它完全绕过了撬:

def suppress_output(&block)
  @original_stderr = $stderr
  @original_stdout = $stdout

  $stderr = $stdout = StringIO.new

  yield(block)

  $stderr = @original_stderr
  $stdout = @original_stdout
  @original_stderr = nil
  @original_stdout = nil
end

我用它替换了它。它停在撬,但继续抑制输出,所以你不能做任何事情:

def suppress_output(&block)
  orig_stderr = $stderr.clone
  orig_stdout = $stdout.clone
  $stderr.reopen File.new("/dev/null", "w")
  $stdout.reopen File.new("/dev/null", "w")
  yield(block)
rescue Exception => e
  $stdout.reopen orig_stdout
  $stderr.reopen orig_stderr
  raise e
ensure
  $stdout.reopen orig_stdout
  $stderr.reopen orig_stderr
end

有没有办法吃我的蛋糕呢?

2 个答案:

答案 0 :(得分:0)

如果有人能想出办法的话,我仍然想要回答这个问题。这不是我在测试中压制STDOUT的唯一时间,并且场景并不总是与此相同。

但是,今天我发现在这个的情况下,更简单的解决方案是更改代码,而不是测试设置。

发电机正在使用Thor,它功能非常强大,但在基础知识方面有非常不透明的文档,并且多年来还没有真正更新过。当我在文档中挖掘时,我发现有一些静音功能。

通过在我的主add_runtime_options!课程中调用Cli < Thor,我获得了全局--quiet选项。这会抑制很多输出,但不是我需要的一切。 #say仍会打印。 #run本身是静音的,但无论我传递给它运行的shell命令都不是。

覆盖这些方法可以解决我的其他问题:

no_commands do
  def quiet?
    !!options[:quiet]
  end

  def run(command, config = {})
    config[:capture] ||= quiet?
    super(command, config)
  end

  def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
    super(message, color, force_new_line) unless quiet?
  end
end

我目前没有一个用例,我只想抑制一些东西,所以现在让它全部或全无效。

现在,我必须使用quiet: true在我的测试中显式创建Cli实例,但是我可以在没有不需要的输出的情况下运行RSpec并且仍然使用pry。

答案 1 :(得分:0)

我发现this solutionChris Hough适用于我的情况,在spec/spec_helper中添加了以下配置:

RSpec.configure do |config|
  config.before(:each) do
    allow($stdout).to receive(:write)
  end
end

这替换了:all之前的块,该块设置了以下内容(并反转了之后的块中的分配):

$stderr = File.open(File::NULL, "w")
$stdout = File.open(File::NULL, "w")

该修复程序仍然抑制输出,同时允许Pry正常运行。