测试电子邮件:通过后台工作人员发送的最后一封电子邮件为零

min*_*ank 4 email testing rspec ruby-on-rails sidekiq

我正在尝试使用这个railscast为电子邮件添加一些测试,但是我得到了undefined method 'to' for nil:NilClass.

这些电子邮件是通过使用一个后台工作实际处理Sidekiq,我知道他们正确地发送,因为他们在生产工作,也是我之前加入,他们将发送require 'sidekiq/testing'spec_helper.rb

所以基本上我的问题是我如何访问Sidekiq的电子邮件?我试图让工作人员处理电子邮件,但仍然遇到同样的错误.

规格/支持/ mailer_macros.rb

module MailerMacros
  def last_email
    ActionMailer::Base.deliveries.last
  end

  def reset_email
    ActionMailer::Base.deliveries = []
  end
end
Run Code Online (Sandbox Code Playgroud)

投机/ spec_helper.rb

require 'sidekiq/testing'
...
config.include MailerMacros
config.before(:each) { reset_email }
Run Code Online (Sandbox Code Playgroud)

配置/环境/ test.rb

config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { host: 'localhost:8080' }
Run Code Online (Sandbox Code Playgroud)

控制器/ tickets_controller.rb

def create
  @ticket = current_user.tickets.build(params[:ticket])   
  if @ticket.save
    Sidekiq::Client.enqueue(TicketNotifier, @ticket.id)
    flash[:success] = "Your ticket has been submitted successfully."
    redirect_to ticket_path(@ticket)
  else
    render 'new'
  end
end
Run Code Online (Sandbox Code Playgroud)

规范的一部分:

require 'spec_helper'

describe "Tickets" do
  subject { page }

  describe "when creating a new ticket successfully" do
    before do
      login_as_user
      visit new_ticket_path
      fill_in "Subject", with: "Test ticket"
      fill_in "Description", with: "This is a test ticket"
      select 'Billing', from: "ticket[category]" 
      click_button "Submit Ticket"
    end

    specify { last_email.to.should include("admin@email.com") }
    # the rest tests the tickets#show view
    it { should have_selector('title', text: "Ticket #1") }
    it { should have_content("ticket has been submitted successfully") }
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)

当我使用时,specify { ActionMailer::Base.deliveries.last.to.should include("admin@email.com") }我得到相同的错误.

Chr*_*son 5

当需要sidekiq/testing和不需要时sidekiq/testing/inline,作业将被放入队列但不执行,直到给出如下命令:

Sidekiq::Extensions::DelayedMailer.drain
Run Code Online (Sandbox Code Playgroud)

我在我的规范中使用了这样的辅助方法:

def process_async
  EventWorker.drain
  Sidekiq::Extensions::DelayedMailer.drain
end
Run Code Online (Sandbox Code Playgroud)

EventWorker可能是我的应用程序中的自定义工作者,并且Sidekiq::Extensions::DelayedMailer默认情况下延迟邮件与Sidekiq一起使用.

我可以有这样的规格:

#do stuff that should send an email and trigger other sidekiq events
...
process_async
...
#assert the email was sent correctly
Run Code Online (Sandbox Code Playgroud)

在SideKiq wiki上有一个很好的解释:https://github.com/mperham/sidekiq/wiki/Testing