如何用RSpec测试日志内容?

How to test log content with RSpec?

比如生成了一个log(my_work.log)内容为:

I, [2015-05-14T00:00:00.000000 #5590]  INFO -- : Work started.

我想测试my_work.log是否有内容Work started.,怎么办?

我不想匹配所有包含日期​​时间的行,因为它包含 #5590,我无法对其进行存根。

可以在初始化Logger时传入StringIO的实例来捕获输出,然后匹配预期的内容:

require 'logger'

describe "log" do
  let(:log) { StringIO.new }
  let(:logger) { Logger.new(log) }
  let(:expected) { "Work started" }

  it "should add the expected content to the log" do
    logger.info(expected)
    log.rewind
    expect(log.read).to match(/.+#{expected}$/)
  end

end

Rails.logger 使用一些方法来记录事情,例如:

  • 调试
  • 信息
  • 致命
  • 警告

因此,在您的情况下,您使用 info 来记录某些内容,而不是查找匹配项,您可以检测是否调用了方法 info

it 'logs exception' do
  # some code
  expect(Rails.logger).to receive(:info)
  # execute the line that logs something
end

甚至你可以用保留字 with:

receive 方法添加参数
expect(Rails.logger).to receive(:info).with('Work started.')

这是因为您需要指定一些内容

勾选rspec and rails logger

同时勾选 this Whosebug post

使用 RSpec 的 output matcher(在 3.0 中引入),您可以执行以下操作:

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

如果是 LoggerLogging 等库,您可能必须使用 output.to_<stdout/stderr>_from_any_process

它简单、干净,并将测试您的消息是否真正到达输出。