2014-11-21 82 views
8

提前致谢! Sidekiq工作得很好,但我无法设法用Devise Async进行测试,还是应该说我无法测试后者?如何使用Sidekiq测试Devise Async?

根据Sidekiq的文档,当测试模式设置为假!时,给工作人员的任何工作被推送到同一个工作人员名为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的两种模式:假的!和内联!

我错过了什么?

回答

1

正如documentation提到的,你可以检查队列大小

Sidekiq::Extensions::DelayedMailer.jobs.size 
+0

我尝试了许多东西。谢谢! – kmanzana 2015-10-06 21:41:32

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 ,水豚 /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