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)语法?
最佳答案
Rails.logger.info method可以采用字符串或块.如果你正在调用块形式,那么它将给出这个“got:(no args)”输出.
例如
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')