【问题标题】:How to test Devise Async with Sidekiq?如何使用 Sidekiq 测试 Devise Async?
【发布时间】:2015-01-19 23:49:11
【问题描述】:

提前致谢! 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 的两种模式:假的!和内联!。

我错过了什么?

【问题讨论】:

    标签: ruby-on-rails-4 devise rspec-rails sidekiq devise-async


    【解决方案1】:

    正如documentation 中提到的,您可以检查队列大小为

    Sidekiq::Extensions::DelayedMailer.jobs.size
    

    【讨论】:

    • ActionMailer::Base.deliveries 是 [] 当我使用 sidekiq 时?我们需要为此做任何配置
    【解决方案2】:

    正在研究这个问题,偶然发现了一个由 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

    【讨论】:

      猜你喜欢
      • 2012-09-03
      • 2021-11-11
      • 2016-11-18
      • 1970-01-01
      • 2014-07-18
      • 2013-05-23
      • 2018-11-06
      • 2019-01-16
      • 2013-03-21
      相关资源
      最近更新 更多