捕获Ruby Logger输出以进行测试

Leo*_*ard 5 ruby logging minitest

我有一个像这样的ruby类:

require 'logger'
class T
  def do_something
    log = Logger.new(STDERR)
    log.info("Here is an info message")
  end
end
Run Code Online (Sandbox Code Playgroud)

这个测试脚本排成一行:

#!/usr/bin/env ruby

gem "minitest"
require 'minitest/autorun'

require_relative 't'

class TestMailProcessorClasses < Minitest::Test
  def test_it
    me = T.new

    out, err = capture_io do
      me.do_something
    end

    puts "Out is '#{out}'"
    puts "err is '#{err}'"
  end
end
Run Code Online (Sandbox Code Playgroud)

当我运行此测试时,out和err都是空字符串.我看到消息打印在stderr上(在终端上).有没有办法让Logger和capture_io很好地一起玩?

我处于直接的Ruby环境中,而不是Ruby on Rails.

bri*_*tea 5

MiniTest #capture_io暂时切换$stdout$stderr用于StringIO捕获写入$stdout或输出的对象$stderr.但Logger它有自己对原始标准错误流的引用,它会愉快地写入.我认为你可以认为这是一个bug或至少是MiniTest的限制#capture_io.

在您的情况下,您正在使用参数创建Logger块内部.仍指向原始标准错误流,这就是它无法按预期工作的原因.#capture_ioSTDERRSTDERR

更改STDERR$stderr(在该点处确实指向StringIO对象)解决此问题,但仅当Logger实际在#capture_io块中创建时,因为在该块之外它指向原始标准错误流.

class T
  def do_something
    log = Logger.new($stderr)
    log.info("Here is an info message")
  end
end
Run Code Online (Sandbox Code Playgroud)


Leo*_*ard 5

神奇的是使用capture_subprocess_io

 out, err = capture_subprocess_io do
     do_stuff
 end
Run Code Online (Sandbox Code Playgroud)