1. ホーム
  2. logging

RSpec:Railsのロガーメッセージの期待値をテストする方法は?

2023-10-20 17:12:40

質問

Railsのロガーが、いくつかの仕様でメッセージを受信することをテストしようとしています。 私は ロギングgem .

こんなクラスがあったとします。

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

specをパスさせるために、いくつかの異なるアプローチを試してみました。 例えばこれは動作します。

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

しかし、このようにアクセス可能なインスタンス変数を設定しなければならないことは、ここでは尻尾が犬を振っているようなものです。(実際、loggerを@logにコピーすることでなぜそれが通るようになるのかさえよくわかりません)。

ロギングをテストするための良い解決策は何ですか?

どのように解決するのですか?

一般的にロガーをテストしたくないということに同意しますが、役に立つ場合もあります。

私は Rails.logger .

RSpecの非推奨の should 構文を使用します。

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

RSpecの新機能を利用する expect の構文を使います。

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

注意 コントローラやモデルの仕様には、次の行を記述する必要があります。 の前に の前に記述する必要があります。もし、これを後に置くと、このようなエラーメッセージが表示されます。

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