【问题标题】:Test ExceptionNotification middleware in rails unit test在 Rails 单元测试中测试 ExceptionNotification 中间件
【发布时间】:2016-01-18 19:35:28
【问题描述】:

我有一个正在测试的服务类。服务类对外部资源进行 API 调用。如果资源返回为空,我想提出一个使用ExceptionNotification gem 发送电子邮件的异常。

这个 gem 作为中间件运行,通常在测试环境中不启用。但是,在我的服务类测试中,我想测试异常通知是否消失,因为通知我们 API 请求失败非常重要。

我对中间件的理解是,它们通常是在请求和应用程序的上下文中。但是,如果我在config/environments/test.rb 中启用ExceptionNotification gem 并运行我的单元测试,则会发送异常通知电子邮件。

所以,我的问题是如何在没有“应用程序”的情况下临时打开和关闭这个中间件来进行这个测试,所以我认为这在没有功能规范的情况下必须是可能的。

好的,这是我正在使用并开始的代码:

class MyService
  ThingNotFound = Class.new(Exception)

  def self.doit(params)
    the_thing = ApiResource.get_the_thing(params)
    raise ThingNotFound unless the_thing.present?
    return the_thing
  rescue ThingNotFound => e
    ExceptionNotifier.notify_exception(e, data: {params: params}) 
  end
end

config/environments/test.rb,这里是ExceptionNotifier中间件代码:

config.before_initialize do 
  MyApp::Application.config.middleware.use ExceptionNotification::Rack
end

【问题讨论】:

    标签: ruby-on-rails ruby rspec rack middleware


    【解决方案1】:

    这是我想出的一个 hacky 方法。对替代品持开放态度。本质上,当您将它包含在 test.rb 中时,它会实例化设置一些类变量的中间件,以便您可以在 Rack 应用程序的上下文之外使用它,因此我们只需要重现它。

     describe 'MyService' do
    
       before { ExceptionNotification::Rack.new(Recognize::Application, email: {:email_prefix => "[PREFIX] ", :sender_address => "whatever@whatever.com", :exception_recipients => %w(noone@noone.com)}) }
       after { ExceptionNotifier.class_variable_set("@@notifiers", {}) }
    
        it 'sends an exception email when no thing is found' do
          ApiResource.stub(get_the_thing: nil)
          expect{ MyService.doit({}) }.to change{ActionMailer::Base.deliveries.length}.by(1)
        end
     end
    

    【讨论】:

    • 注意:我不使用 middleware.use 的更高级别的接口,因为数组被冻结了。所以这就是你解决这个问题的方法。耶,红宝石!
    • 什么是Recognize::Application
    • 这只是我的应用程序的名称
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多