logging - RSpec:如何测试 Rails 记录器消息期望?

标签 logging rspec mocking stubbing

我正在尝试测试 Rails 记录器是否接收我的某些规范中的消息。我正在使用Logging gem .

假设我有一个这样的类(class):

class BaseWorker

  def execute
    logger.info 'Starting the worker...'
  end

end

规范如下:

describe BaseWorker do

  it 'should log an info message' do
    base_worker = BaseWorker.new
    logger_mock = double('Logging::Rails').as_null_object
    Logging::Rails.stub_chain(:logger, :info).and_return(logger_mock)

    logger_mock.should_receive(:info).with('Starting the worker...')
    base_worker.execute
    Logging::Rails.unstub(:logger)
  end

end

我收到以下失败消息:

 Failure/Error: logger_mock.should_receive(:info).with('Starting worker...')
   (Double "Logging::Rails").info("Starting worker...")
       expected: 1 time
       received: 0 times

我尝试了几种不同的方法来让规范通过。例如,这有效:

class BaseWorker

  attr_accessor :log

  def initialize
    @log = logger
  end

  def execute
    @log.info 'Starting the worker...'
  end

end

describe BaseWorker do
  it 'should log an info message' do
    base_worker = BaseWorker.new
    logger_mock = double('logger')
    base_worker.log = logger_mock

    logger_mock.should_receive(:info).with('Starting the worker...')
    base_worker.execute
  end
end

但是必须像这样设置一个可访问的实例变量,这似乎是尾部在摇狗。 (实际上,我什至不确定为什么将记录器复制到 @log 会让它通过。)

测试日志记录的好解决方案是什么?

最佳答案

虽然我同意您通常不想测试记录器,但有时它可能很有用。

我在 Rails.logger 上取得了预期的成功。

使用 RSpec 已弃用的 should 语法:

Rails.logger.should_receive(:info).with("some message")

使用 RSpec 较新的 expect 语法:

expect(Rails.logger).to receive(:info).with("some message")

注意:在 Controller 和模型规范中,您必须将此行放在记录消息之前。如果你把它放在后面,你会收到如下错误消息:

Failure/Error: expect(Rails.logger).to receive(:info).with("some message")
       (#<ActiveSupport::Logger:0x007f27f72136c8>).info("some message")
           expected: 1 time with arguments: ("some message")
           received: 0 times

关于logging - RSpec:如何测试 Rails 记录器消息期望?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10998160/

相关文章:

unit-testing - 关于与其他方法组合的stubbing方法的问题

ruby-on-rails - Rails - 请求的完成时间明显高于 View 和 DB 时间

java - Camel 主体是用请求而不是响应设置的

python - 日志记录模块不写入文件

ruby-on-rails - 为什么我的 rspec 测试失败?

ruby-on-rails - Rails 自定义生成器组

c++ - 线程安全运算符<<

ruby-on-rails - 找不到 'rspec' 生成器

Python:如何实现多个动态mock.patch函数?

unit-testing - 用 Mockito 模拟返回一个 InvocationTargetException