подавление вывода к консоли с рубином

Используйте автозапись опция:

:set autowrite

Запись содержание файла, если это было изменено на каждом: затем: перемотка: в последний раз: во-первых: предыдущий: остановитесь: приостановите: тег, :! : сделайте, CTRL-] и команда CTRL-^ [...]

18
задан the Tin Man 7 August 2013 в 14:27
поделиться

2 ответа

I use the following snippet in tests to capture and test STDOUT

def capture_stdout(&block)
  original_stdout = $stdout
  $stdout = fake = StringIO.new
  begin
    yield
  ensure
    $stdout = original_stdout
  end
  fake.string
end

With this method, the above would become:

def executing_a_signal
  capture_stdout { a_method(a_signal.new, a_model, a_helper) }
  assert_equal(new_state, a_model.state)
end
32
ответ дан 30 November 2019 в 06:50
поделиться

Есть два решения: перенаправление туда, куда помещает запись (решение, данное @cldwalker выше), или перезапись метода ставит сам метод , чтобы он не выполнялся. (Реализация должна быть очевидной: ядро ​​модуля; def put (* args) end end ).

Однако в этом случае лучшим решением действительно будет " прислушиваясь к вашим тестам ". Потому что часто, когда что-то неудобно проверить, ваши тесты действительно пытаются сказать вам, что что-то не так с вашим дизайном. В этом случае я чувствую нарушение принципа единой ответственности: какого черта объекту модели нужно знать, как писать в консоль? В его обязанности входит представление концепции домена, а не ведение журнала! Вот для чего нужны объекты Logger!

Таким образом, альтернативным решением было бы, чтобы объект Model делегировал ответственность за ведение журнала объекту Logger и использовал инъекцию зависимостей, чтобы внедрить объект Model с подходящим объектом Logger. Таким образом, вы можете просто ввести для теста поддельный регистратор. Вот пример:

#!/usr/bin/env ruby

class SomeModel
  def initialize(logger=Kernel) @logger = logger end
  def some_method_that_logs; @logger.puts 'bla' end
end

require 'test/unit'
require 'stringio'
class TestQuietLogging < Test::Unit::TestCase
  def setup; @old_stdout, $> = $>, (@fake_logdest = StringIO.new) end
  def teardown; $> = @old_stdout end

  def test_that_default_logging_is_still_noisy
    SomeModel.new.some_method_that_logs

    assert_equal "bla\n", @fake_logdest.string
  end

  def test_that_logging_can_be_made_quiet
    fake_logger = Object.new
    def fake_logger.puts *args; end

    SomeModel.new(fake_logger).some_method_that_logs

    assert_equal '', @fake_logdest.string
  end
end

По крайней мере, объект Model должен принимать объект IO , который он регистрирует в в качестве аргумента, чтобы вы могли просто ввести StringIO. new для теста:

#!/usr/bin/env ruby

class SomeModel
  def initialize(logdest=$>) @logdest = logdest end
  def some_method_that_logs; @logdest.puts 'bla' end
end

require 'test/unit'
require 'stringio'
class TestQuietLogging < Test::Unit::TestCase
  def setup; @old_stdout, $> = $>, (@fake_logdest = StringIO.new) end
  def teardown; $> = @old_stdout end

  def test_that_default_logging_is_still_noisy
    SomeModel.new.some_method_that_logs

    assert_equal "bla\n", @fake_logdest.string
  end

  def test_that_logging_can_be_made_quiet
    fake_logdest = (@fake_logdest = StringIO.new)

    SomeModel.new(fake_logdest).some_method_that_logs

    assert_equal '', @fake_logdest.string
    assert_equal "bla\n", fake_logdest.string
  end
end

Если вы все еще хотите иметь возможность просто сказать, что помещает все, что в вашу Модель, или вы боитесь, что кто-то может забыть позвонить put ] в объекте регистратора, вы можете предоставить свой собственный (частный) метод помещения:

class SomeModel
  def initialize(logdest=$>) @logdest = logdest end
  def some_method_that_logs; puts 'bla' end
  private
  def puts(*args) @logdest.puts *args end
end
4
ответ дан 30 November 2019 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: