web-dev-qa-db-ja.com

RspecでのSTDOUT出力のテスト

この声明の仕様を作成しようとしています。 「プット」で簡単です

print "'#{@file}' doesn't exist: Create Empty File (y/n)?"
41
user2292710

RSpec 3.0+

RSpec 3.0 新しいoutput matcherを追加 この目的のため:

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
79
Patrick Oscity

あなたの目標がこの方法をテストすることだけである場合、私はこのようにします:

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

ただし、このようなメソッドを直接テストしないことに注意してください。代わりに、それを使用するコードをテストします。私は昨日、見習い生と話をしていたが、彼は非常に似たようなことをしていたので、私は彼と一緒に座って、クラスの一部を再実装しました。 here

また、この種のことについて話す blog もあります。

3
Joshua Cheek