【问题标题】:How to ensure background jobs run in integration tests?如何确保后台作业在集成测试中运行?
【发布时间】:2019-01-02 19:26:33
【问题描述】:

我有一个通过 capybara 运行的集成测试。它访问网页、创建对象并呈现结果。创建对象时,控制器会将创建一些相关对象的多个作业排入队列。

当我运行集成测试时,我希望能够检查呈现的页面,就好像这些作业已经完成一样。两个明显的解决方案是:

  1. 将队列适配器设置为 :inline
  2. 在创建对象后手动执行/清除排队的作业。

对于 1),我尝试将 before(:each) 中的队列适配器设置为 :inline,但这不会更改适配器,它会继续使用测试适配器(在我的 test.rb 配置中设置文件):

before(:each) { ActiveJob::Base.queue_adapter = :inline }
after(:each) { ActiveJob::Base.queue_adapter = :test }
it "should work" do
  puts ActiveJob::Base.queue_adapter
end

哪个输出:#<ActiveJob::QueueAdapters::TestAdapter:0x007f93a1061ee0 @enqueued_jobs=[], @performed_jobs=[]>

对于 2),我不确定这是否真的可行。 ActiveJob::TestHelpers 提供了 perform_enqueued_jobs,但这种方法没有帮助,因为它似乎只适用于传入块中明确引用的作业。

【问题讨论】:

    标签: ruby-on-rails-5 capybara rails-activejob


    【解决方案1】:

    假设您正在使用 RSpec,使用 perform_enqueued_jobs 的最简单方法是使用 around 块。将它与元数据标签结合起来,你可以做类似的事情

    RSpec.configure do |config|
      config.include(RSpec::ActiveJob)
    
      # clean out the queue after each spec
      config.after(:each) do
        ActiveJob::Base.queue_adapter.enqueued_jobs = []
        ActiveJob::Base.queue_adapter.performed_jobs = []
      end
    
      config.around :each, perform_enqueued: true do |example|
        @old_perform_enqueued_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
        ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
        example.run
        ActiveJob::Base.queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs
      end
    
      config.around :each, peform_enququed_at: true do |example|
        @old_perform_enqueued_at_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs
        ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
        example.run
        ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs
      end
    end
    

    注意:如果 queue_adapter 尚未设置,则需要在 config/environments/test.rb 中将 queue_adapter 指定为 :test

    然后您可以在测试中指定 :perform_enqueued 元数据,并且指定的任何作业都将运行

    it "should work", :perform_enqueued do
      # Jobs triggered in this test will be run
    end
    

    【讨论】:

    • 我后来找到了这个,stackoverflow.com/questions/27859731/…。这非常相似。
    • 你知道,这实际上在我的功能测试(capybara)中不起作用。我已经确认正在执行 around 块。有任何想法吗?此外,上述代码中不需要“rspec/active_job”
    • @cgat 您已将 queue_adapter 保留为 :test 正确吗?由于该块正在运行 - 检查 ActiveJob::Base.queue_adapter.enqueued_jobs 和 example.run 之后的 ActiveJob::Base.queue_adapter.performed_jobs 的内容,并查看您认为正在排队的作业是否实际上是
    • @cgat 实际上,您可能需要在 after 块的开头检查它们,因为 IIRC 正确,它将在 example.run 返回之前运行。
    • 所以我想我已经解决了这个问题。看来我的测试有一个不同的测试适配器实例,而不是在周围回调中引用的那个。因此,即使我在 around 回调的测试适配器中将 perform_enqueued_jobs 设置为 true,我在测试中也没有看到这一点。如果我在规范示例中内联行为,它会起作用。我不知道其他测试适配器实例来自哪里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2012-11-26
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2013-10-02
    • 2011-02-02
    相关资源
    最近更新 更多