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

Ruby on rails 测试电子邮件:通过后台工作人员发送的最后一封电子邮件为零,ruby-on-rails,email,testing,rspec,sidekiq,Ruby On Rails,Email,Testing,Rspec,Sidekiq,我试图使用添加一些电子邮件测试,但是我得到了nil:NilClass的未定义方法to 这些电子邮件实际上是通过后台工作人员使用进行处理的,我知道它们发送正确,因为它们在生产环境中工作,而且在我向spec_helper.rb添加require'sidekiq/testing'之前,它们也会发送 所以基本上我的问题是如何在Sidekiq中访问电子邮件?我曾尝试让员工处理电子邮件,但仍然出现相同的错误 spec/support/mailer_macros.rb module MailerMacros

我试图使用添加一些电子邮件测试,但是我得到了nil:NilClass的未定义方法to

这些电子邮件实际上是通过后台工作人员使用进行处理的,我知道它们发送正确,因为它们在生产环境中工作,而且在我向
spec_helper.rb添加
require'sidekiq/testing'
之前,它们也会发送

所以基本上我的问题是如何在Sidekiq中访问电子邮件?我曾尝试让员工处理电子邮件,但仍然出现相同的错误

spec/support/mailer_macros.rb

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

  def reset_email
    ActionMailer::Base.deliveries = []
  end
end
spec/spec_helper.rb

require 'sidekiq/testing'
...
config.include MailerMacros
config.before(:each) { reset_email }
config/environments/test.rb

config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { host: 'localhost:8080' }
控制器/票证\u 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
规范的一部分:

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

当我使用
时,指定{ActionMailer::Base.deliveries.last.to.should include(“admin@email.com)相反,我得到了相同的错误。

当需要
sidekiq/testing
而不是
sidekiq/testing/inline
时,作业被放在队列上,但在发出类似这样的命令之前不会执行:

Sidekiq::Extensions::DelayedMailer.drain
我在我的规范中使用了这样的帮助器方法:

def process_async
  EventWorker.drain
  Sidekiq::Extensions::DelayedMailer.drain
end
其中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
describe "Tickets", :sidekiq => :inline 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

SideKiq wiki上有一个很好的解释:

除了cmaitchison的答案之外,我还这样做了(在他们的wiki上:)

这样做你的测试:

#do stuff that should send an email and trigger other sidekiq events
...
process_async
...
#assert the email was sent correctly
describe "Tickets", :sidekiq => :inline 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

你能试试这个吗
指定{MailerMacros.last_email.should include(@user.email)}
然后根据我之前运行的railscasts和类似宏,我得到了MailerMacros:Module
未定义的方法“last_email”。last_email
应该可以工作。我的错误,你是正确的,我没有经过正确的思考就猜到了。刚刚通过了railscast,在你的情况下,它就来了
nil:NilClass
,所以我只能期望有一个原因是
邮件真的被发送了吗?
是的,如果我删除
要求“sidekiq/测试”
,那么sidekiq实际上会向我的收件箱发送一封电子邮件。太好了!谢谢你解释它是如何工作的,我读了维基,但没有完全理解它。