我想测试正在生成的特定日志,这些日志是我代码的一部分。虽然测试Rails.logger似乎相当简单,但我正在用ActiveSupport::TaggedLogging包装它,我在用它进行测试时遇到了问题.
这里有两种方法:
def logger
@logger = ActiveSupport::TaggedLogging.new(Rails.logger)
end
def log(message)
logger.tagged('MangaDex::Importer', "User ##{@current_user_id}") do
logger.info message
end
end然后我在代码中这样称呼它:
if md_parsed_list.blank?
log 'List is inaccessible'
return
end现在,在我的Rspec测试中,我一直在尝试这样做:
it 'logs and stops execution if there is nothing to import' do
expect(Spiders::Mangadex).to receive(:parse!)
.with(:parse, url: import_url)
.and_return({})
expect(ActiveSupport::TaggedLogging).to receive(Rails.logger)
expect(Rails.logger).to receive(:info).with('List is inaccessible')
expect(CreateMangaEntries).not_to receive(:call)
described_class.perform_async(import_url, user.id)
described_class.drain
end我知道我在连接TaggedLogging和Rails.logger方面遗漏了一些步骤,因为调用上面的测试只会抛出一个错误undefined method 'to_sym' for #<ActiveSupport::Logger:0x00007f8fc545db50>。
希望能在这方面得到一些帮助,谢谢!
编辑:
在改进了基于@Grzegorz的模拟之后,测试结果如下所示:
let(:tagged_logger_double) { instance_double(ActiveSupport::Logger) }
it 'logs and stops execution if MDList is inaccessible' do
expect(Spiders::Mangadex).to receive(:parse!)
.with(:parse, url: import_url)
.and_return(nil)
expect(ActiveSupport::TaggedLogging)
.to receive(:new)
.with(Rails.logger)
.and_return(tagged_logger_double)
expect(CreateMangaEntries).not_to receive(:call)
expect(tagged_logger_double).to receive(:info).with('List is inaccessible')
described_class.perform_async(import_url, user.id)
described_class.drain
end由于ActiveSupport::TaggedLogging的实例是ActiveSupport::Logger,所以我不得不稍微更改double。
我能够解决原始异常,但仍然无法测试receive(:info),因为tagged似乎缺少:#<InstanceDouble(ActiveSupport::Logger) (anonymous)> received unexpected message :tagged with ("MangaDex::Importer", "User #2626")
但是,当我尝试存根该方法时:allow(tagged_logger_double).to receive(:tagged),我得到这样的方法不存在的错误:the ActiveSupport::Logger class does not implement the instance method: tagged,when,我仍然被一个失败的测试所困扰。
发布于 2019-12-31 10:13:29
格雷斯正确回答了你问题的第一部分,所以说到他停下来的地方.
你是对的,你需要存根tagged。获得未实现错误的方法的原因是因为ActiveSupport::Logger没有实现tagged。它在被ActiveSupport::TaggedLogging包装时是扩展的。
请参见此处的构造函数方法定义:https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html#method-c-new
我不知道在这种情况下如何使用验证码。一种选择是不要这样做,只需使用double。
另一个问题是,您没有正确地处理tagged。您需要对其进行存根处理,以便使其屈服于块。
最后,您需要回溯logger方法的返回值,因为您希望ActiveSupport::TaggedLogging只接收new一次。
将所有这些结合在一起,我编写了以下测试:
require "rails_helper"
require "custom_logger"
RSpec.describe "CustomLogger" do
let(:tagged_logger_double) { double("Tagged logger") }
it "logs" do
expect(ActiveSupport::TaggedLogging)
.to receive(:new)
.with(Rails.logger)
.and_return(tagged_logger_double)
allow(tagged_logger_double)
.to receive(:tagged)
.and_yield
expect(tagged_logger_double).to receive(:info).with("message")
CustomLogger.new.log("message")
end
end这与下面的代码一起传递,我认为它与您的示例中的代码非常相似:
class CustomLogger
def log(message)
logger.tagged("Tag") do
logger.info message
end
end
def logger
@_logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
end
end发布于 2019-11-23 16:11:34
您已经将一个对象传递给.to receive方法,在该方法中,它需要一个方法名(字符串或符号)。这是您错误的根源,下面的内容对我来说更有意义:
expect(ActiveSupport::TaggedLogging)
.to receive(:new)
.with(Rails.logger)
.and_return(tagged_logger_double)如果这样定义的话,您就可以完全访问规范中的记录器。
let(:tagged_logger_double) { instance_double(ActiveSupport::TaggedLogging) }并设定你的期望
expect(tagged_logger_double).to receive(:info).with('List is inaccessible')发布于 2021-10-13 08:20:16
我需要测试已经记录的标签和消息。这个密码对我有用。
let(:logger) { ActiveSupport::TaggedLogging.new(Rails.logger) }
before do
allow(logger).to receive(:tagged).and_call_original
allow(logger).to receive(:info).and_call_original
allow(ActiveSupport::TaggedLogging).to receive(:new).and_return(logger)
end
it 'logs with correct tags' do
expect(logger).to have_received(:tagged).with(tags)
end
it 'logs with correct message' do
expect(logger).to have_received(:info).with(message)
endhttps://stackoverflow.com/questions/59009116
复制相似问题