8

提前致谢!Sidekiq 工作得很好,但我无法使用 Devise Async 对其进行测试,或者我应该说我无法测试后者?

根据 Sidekiq 的文档,当测试模式设置为 fake! 时,分配给工作人员的任何工作都会被推送到以该工作人员命名的数组jobs中。所以测试这个数组的增加是微不足道的。

但是,使用 Devise Async,它并不是那么简单,尽管它的后端包括Sidekiq::Worker. 这是我尝试测试的一小部分内容:

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

这些测试对象都没有指出尺寸增加。由于 Devise 将其电子邮件作为模型回调发送,因此我尝试在模型和控制器规范中进行测试。使用 Factory Girl 和 Database Cleaner,我还尝试了两种模式:事务和截断。不用说,我也尝试了 Sidekiq 的两种模式:假的!和内联!

我错过了什么?

4

2 回答 2

1

文档中所述,您可以将队列大小检查为

Sidekiq::Extensions::DelayedMailer.jobs.size
于 2015-07-08T13:33:51.093 回答
0

正在研究这个问题,偶然发现了一个由 gitlab 完成的漂亮实现,我认为这可能有助于测试通过 sidekiq 队列推送的设计异步或电子邮件。 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
于 2016-05-11T02:25:50.353 回答