Подтвердить что ты не робот

Тестирование вывода STDOUT в Rspec

Я пытаюсь создать спецификацию для этого утверждения. Это легко с помощью "puts"

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

Ответ 1

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

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

Ответ 2

Если ваша цель состоит в том, чтобы проверить этот метод, я бы сделал это следующим образом:

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

Тем не менее, я хочу указать, что я не буду тестировать такой метод напрямую. Вместо этого я бы тестировал код, который его использует. Вчера я разговаривал с потенциальным учеником, и он делал что-то очень похожее, поэтому я сел с ним, и мы переопределили часть класса, вы можете видеть, что .

У меня также есть blog, в котором говорится об этом.