如何从Rspec功能规范测试Rails日志记录?

时间:2016-07-25 02:53:28

标签: ruby-on-rails ruby logging rspec

This question告诉我如何从RSpec模型和控制器规范测试记录器语句。不幸的是,它似乎不适用于功能规范。使用此代码:

# controller.rb
def action
  logger.info 'foobar'
end

# spec.rb
scenario 'logging should work' do
  expect(Rails.logger).to receive(:info).with('foobar')
  visit action_path
end

我收到错误:

 Failure/Error: visit action_path
   #<ActiveSupport::Logger:0x007ff45b6e5ad0> received :info with unexpected arguments
     expected: ("foobar")
          got: (no args)

test.log文件不包含foobar,因此在控制器操作有机会完成之前,测试似乎立即失败。

是否有某种方法可以在功能规范中使用此expect(Rails.logger)语法?

1 个答案:

答案 0 :(得分:2)

Rails.logger.info method可以采用字符串或块。如果你正在调用阻止形式,那么它将给出这个&#34; got :( no args)&#34;输出

例如

logger.info 'foobar'

...所有在一行中都会使用字符串调用.info,但如果你这样做

logger.info
  "foobar foobar longer message so I'll put it on its own line"

在没有括号的情况下分成两行,然后你实际上传递了一个块。添加一些括号......

logger.info(
  "foobar foobar longer message so I'll put it on its own line"
)

...而且你又回到了一个字符串。

他在几个小时后对这个问题进行了猛烈抨击后明知道: - )

在实现这一点之前,我开始弄清楚如何模拟Rails.logger类。这对您或其他人来说可能是一种有用的方法。也许你因为某些其他原因而调用了一个块(与功能与控制器规格有关?),或者你可能无法更改调用代码,在这种情况下......这样的事情可能是一个有用的起点:

class LoggerMock < Object
  def initialize; end

  def info(progname = nil, &block)
    mock_info(block.call)
  end
end

logger_mock = LoggerMock.new
allow(Rails).to receive(:logger).and_return(logger_mock)
expect(logger_mock).to receive(:mock_info).with('foobar')