如何使用Sidekiq测试Devise异步功能?

8

提前感谢!Sidekiq运作良好,但我无法使用Devise Async进行测试,或者说我不能测试后者?

根据Sidekiq的文档,在将测试模式设置为fake!时,分配给worker的任何作业都会被推送到该worker的名为jobs的数组中。因此,测试该数组增加是微不足道的。

但是,对于Devise Async而言,这并不那么微不足道,尽管其后端包括Sidekiq::Worker。以下是我尝试测试的一些内容:

  • Devise::Async::Backend::Sidekiq.jobs
  • Devise::Mailer.deliveries
  • ActionMailer::Base.deliveries
  • Devise::Async::Backend::Worker.jobs

这些测试主题都没有指向任何大小的增加。由于Devise将其电子邮件作为模型回调发送,因此我尝试在模型和控制器spec中进行测试。我还使用Factory Girl和Database Cleaner尝试了两种模式:transaction和truncation。不用说,我也尝试了Sidekiq的两种模式:fake!和inline!。

我错过了什么?

2个回答

1
文档中所述,您可以检查队列大小。
Sidekiq::Extensions::DelayedMailer.jobs.size

当我使用Sidekiq时,ActionMailer :: Base.deliveries被[]?我们需要进行任何配置吗? - yaswant singh

0

正在解决这个问题,偶然发现了GitLab实现的一个美妙实现,我觉得这可能有助于测试通过Sidekiq队列推送的Devise-async或电子邮件。 spec_helper.rb email_helpers.rb

通过在spec_helper.rb中添加这些行

# An inline mode that runs the job immediately instead of enqueuing it
require 'sidekiq/testing/inline'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
  config.include EmailHelpers
  # other configurations line
end

并添加/spec/support/email_helpers.rb

module EmailHelpers
  def sent_to_user?(user)
    ActionMailer::Base.deliveries.map(&:to).flatten.count(user.email) == 1
  end

  def should_email(user)
    expect(sent_to_user?(user)).to be_truthy
  end

  def should_not_email(user)
    expect(sent_to_user?(user)).to be_falsey
  end
end

如果你要运行测试,例如测试忘记密码功能,我假设你已经了解了rspec、factorygirl和capybara。

/spec/features/password_reset_spec.rb
require 'rails_helper'

feature 'Password reset', js: true do
  describe 'sending' do
    it 'reset instructions' do
      #FactoryGirl create
      user = create(:user)
      forgot_password(user)

      expect(current_path).to eq(root_path)
      expect(page).to have_content('You will receive an email in a few minutes')
      should_email(user)
    end
  end

  def forgot_password(user)
    visit '/user/login'
    click_on 'Forgot password?'
    fill_in 'user[email]', with: user.email
    click_on 'Reset my password'
    user.reload
  end
end

您会注意到在这个测试实现中

  1. 将导致sidekiq运行作业而不是将其排队,
  2. 用户模型电子邮件属性必须称为email或者您可以替换上面的代码。
  3. ActionMailer::Base.deliveries.map(&:to).flatten.count(user.email) == 1检查ActionMailer::Base.deliveries是否发送到user.email

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接