首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何测试ActiveSupport::TaggedLogging

如何测试ActiveSupport::TaggedLogging
EN

Stack Overflow用户
提问于 2019-11-23 15:21:35
回答 3查看 1.1K关注 0票数 3

我想测试正在生成的特定日志,这些日志是我代码的一部分。虽然测试Rails.logger似乎相当简单,但我正在用ActiveSupport::TaggedLogging包装它,我在用它进行测试时遇到了问题.

这里有两种方法:

代码语言:javascript
运行
复制
  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

然后我在代码中这样称呼它:

代码语言:javascript
运行
复制
    if md_parsed_list.blank?
      log 'List is inaccessible'
      return
    end

现在,在我的Rspec测试中,我一直在尝试这样做:

代码语言:javascript
运行
复制
  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的模拟之后,测试结果如下所示:

代码语言:javascript
运行
复制
  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,我仍然被一个失败的测试所困扰。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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一次。

将所有这些结合在一起,我编写了以下测试:

代码语言:javascript
运行
复制
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

这与下面的代码一起传递,我认为它与您的示例中的代码非常相似:

代码语言:javascript
运行
复制
class CustomLogger
  def log(message)
    logger.tagged("Tag") do
      logger.info message
    end
  end

  def logger
    @_logger ||= ActiveSupport::TaggedLogging.new(Rails.logger)
  end
end
票数 4
EN

Stack Overflow用户

发布于 2019-11-23 16:11:34

您已经将一个对象传递给.to receive方法,在该方法中,它需要一个方法名(字符串或符号)。这是您错误的根源,下面的内容对我来说更有意义:

代码语言:javascript
运行
复制
expect(ActiveSupport::TaggedLogging)
  .to receive(:new)
  .with(Rails.logger)
  .and_return(tagged_logger_double)

如果这样定义的话,您就可以完全访问规范中的记录器。

代码语言:javascript
运行
复制
let(:tagged_logger_double) { instance_double(ActiveSupport::TaggedLogging) }

并设定你的期望

代码语言:javascript
运行
复制
expect(tagged_logger_double).to receive(:info).with('List is inaccessible')
票数 3
EN

Stack Overflow用户

发布于 2021-10-13 08:20:16

我需要测试已经记录的标签和消息。这个密码对我有用。

代码语言:javascript
运行
复制
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)
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59009116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档