我正在尝试使用Sidekiq测试发送电子邮件,但出现错误,这意味着它没有进入队列,因为我的测试表明它的大小没有从0更改为1。可能是我遗漏了一些东西,或者该如何解决?
错误
expected `Array#size` to have changed by 1, but was changed by 0
0) Sending Mail sends email to sidekiq
Failure/Error:
expect do
OrderPointsMailer.paid_order_email(customer_detail.id).deliver_later
end.to change(Sidekiq::Worker.jobs, :size).by(1)
expected `Array#size` to have changed by 1, but was changed by 0
# ./spec/requests/order_points_mailer_spec.rb:9:in `block (2 levels) in <top (required)>'
1 example, 1 failure, 0 passed
binding.pry
这表明Sidekiq::Worker.jobs
是empty array
,可以理解为什么它失败了,但我不知道该如何解决。
[1] pry(#<RSpec::ExampleGroups::SendingMailWithSidekiq>)>Sidekiq::Worker.jobs
=> []
app / jobs / order_points_job.rb
# frozen_string_literal: true
class OrderPointsJob < ApplicationJob
def perform(customer_email)
customer_detail = CustomerDetail.find_by(email: customer_email)
return unless customer_detail
OrderPointsMailer.paid_order_email(customer_detail.id).deliver_later # This call send email to sidekiq process
end
end
RSpec
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Sending Mail with Sidekiq', type: :request do
it 'sends email to sidekiq' do
customer_detail = create(:customer_detail)
expect do
OrderPointsMailer.paid_order_email(customer_detail.id).deliver_later
end.to change(Sidekiq::Worker.jobs, :size).by(1)
end
end
rails_helper.rb
require 'sidekiq/testing'
Sidekiq::Testing.fake!
答案 0 :(得分:0)
您可能应该使用方法count
而不是size
:
.to change(Sidekiq::Worker.jobs.reload, :count).by(1)
看看size
的实现:
From: /home/toptal/.rvm/gems/ruby-2.5.5/gems/activerecord-6.0.0/lib/active_record/relation.rb @ line 260:
Owner: ActiveRecord::Relation
Visibility: public
Number of lines: 3
def size
loaded? ? @records.length : count(:all)
end
还要看看匹配器的实现(https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/built_in/change.rb#L82:L85)
我猜测接收器(在您的情况下为Sidekiq::Worker.jobs
)将被评估一次,然后size
将在相同的对象集合上被调用两次,而无需重新加载。
您可以采用的另一种方法是
.to change { Sidekiq::Worker.jobs.reload.size }.by(1)
但是如果您在数据库中有更多记录,这将有点浪费,因为每次都需要创建AR对象(并且不使用它们)