为啥在请求测试中不使用 ActiveJob InlineAdapter?
Posted
技术标签:
【中文标题】为啥在请求测试中不使用 ActiveJob InlineAdapter?【英文标题】:Why is ActiveJob InlineAdapter not used in request tests?为什么在请求测试中不使用 ActiveJob InlineAdapter? 【发布时间】:2021-12-19 15:48:01 【问题描述】:我的 test.rb 中有这段代码:
config.active_job.queue_adapter = :inline
在测试中我有:
scenario '15 minutes after last call a recall should happen' do
p ActiveJob::Base.queue_adapter
end
这会返回: ActiveJob::QueueAdapters::InlineAdapter
这很好,因为 perform_later 会立即执行。
但是,当我像这样将 type: :request 添加到测试中时:
scenario '15 minutes after last call a recall should happen', type: :request do
p ActiveJob::Base.queue_adapter
end
我得到:requestActiveJob::QueueAdapters::TestAdapter 并且 perform_later 不再执行。这是预期的行为吗?如何确保 perform_later 块始终在测试中执行?
【问题讨论】:
【参考方案1】:作业不会排队执行,但会排队检查是否已排队(basically just saved in an array,因此您可以测试它们是否存在):
https://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters/TestAdapter.html
既然你用 rspec 标记了这个问题,那么你就有了完美的匹配器:have_been_enqueued
,可以这样使用:
RSpec.describe UploadBackupsJob do
it "matches with enqueued job" do
ActiveJob::Base.queue_adapter = :test
UploadBackupsJob.perform_later
expect(UploadBackupsJob).to have_been_enqueued
end
end
【讨论】:
如何确保 perform_later 块始终在测试中执行?当不包括类型请求时,它们被执行。即使我指定了我想要内联适配器,为什么它使用不同的队列适配器?【参考方案2】:这和这个问题有关:https://github.com/rails/rails/issues/37270
投入
(ActiveJob::Base.descendants << ActiveJob::Base).each(&:disable_test_adapter)
在实际测试中修复它。
另一个更简洁的选择是(如果可能)将测试类型更改为:type: :system 并确保您的 rspec-rails 版本 >= 4.1
【讨论】:
以上是关于为啥在请求测试中不使用 ActiveJob InlineAdapter?的主要内容,如果未能解决你的问题,请参考以下文章