红宝石-在Rsp中测试STDOUT输出

我正在尝试为此声明建立规范。 使用“ puts”很容易

print "'#{@file}' doesn't exist: Create Empty File (y/n)?"
user2292710 asked 2020-08-12T09:01:18Z
2个解决方案
81 votes

RSpec 3.0+

RSpec 3.0为此添加了一个新的output匹配器:

expect { my_method }.to output("my message").to_stdout
expect { my_method }.to output("my error").to_stderr

迷你测试

Minitest也有一个称为capture_io的东西:

out, err = capture_io do
  my_method
end

assert_equals "my message", out
assert_equals "my error", err

RSpec <3.0(及其他)

对于RSpec <3.0和其他框架,可以使用以下帮助器。 这将允许您捕获分别发送到stdout和stderr的任何内容:

require 'stringio'

def capture_stdout(&blk)
  old = $stdout
  $stdout = fake = StringIO.new
  blk.call
  fake.string
ensure
  $stdout = old
end

def capture_stderr(&blk)
  old = $stderr
  $stderr = fake = StringIO.new
  blk.call
  fake.string
ensure
  $stderr = old
end

现在,当您有一种方法应该将某些内容打印到控制台上时

def my_method
  # ...
  print "my message"
end

您可以编写这样的规范:

it 'should print "my message"' do
  printed = capture_stdout do
    my_method # do your actual method call
  end

  printed.should eq("my message")
end
Patrick Oscity answered 2020-08-12T09:01:54Z
3 votes

如果您的目标只是能够测试此方法,我将这样做:

class Executable
  def initialize(outstream, instream, file)
    @outstream, @instream, @file = outstream, instream, file
  end

  def prompt_create_file
    @outstream.print "'#{@file}' doesn't exist: Create Empty File (y/n)?"
  end
end


# when executing for real, you would do something like
# Executable.new $stdout, $stdin, ARGV[0]

# when testing, you would do
describe 'Executable' do
  before { @input = '' }
  let(:instream)   { StringIO.new @input }
  let(:outstream)  { StringIO.new }
  let(:filename)   { File.expand_path '../testfile', __FILE__ }
  let(:executable) { Executable.new outstream, instream, filename }

  specify 'prompt_create_file prompts the user to create a new file' do
    executable.prompt_create_file
    outstream.string.should include "Create Empty File (y/n)"
  end
end

但是,我想指出的是,我不会直接测试这样的方法。 相反,我将测试使用它的代码。 昨天我正在和一个潜在的学徒交谈,他的工作非常相似,所以我和他坐下,然后我们重新安排了部分课程,您可以在这里看到。

我也有一个博客谈论这种事情。

Joshua Cheek answered 2020-08-12T09:02:24Z
translate from https://stackoverflow.com:/questions/16507067/testing-stdout-output-in-rspec