如果发送电子邮件,如何使用Rspec进行测试

fos*_*l12 35 rspec2 ruby-on-rails-3

如果我使用:post调用控制器方法,我想测试是否发送了电子邮件.我将使用email_spec,所以我在这里尝试了这个:http://rubydoc.info/gems/email_spec/1.2.1/file/README.rdoc#Testing_In_Isolation

但它不起作用,因为我将model-object的实例传递给delivery-method,并且在传递之前保存实例.

我试图创建一个model-object的另一个实例,但后来id不一样.

我的控制器方法如下所示:

def create

   @params = params[:reservation]

   @reservation = Reservation.new(@params)
   if @reservation.save
      ReservationMailer.confirm_email(@reservation).deliver
      redirect_to success_path
   else
      @title = "Reservation"
      render 'new'
   end

end
Run Code Online (Sandbox Code Playgroud)

你有什么想法解决这个问题吗?

Cho*_*ett 56

假设您的测试环境是以通常的方式设置的(也就是您拥有的config.action_mailer.delivery_method = :test),那么交付的电子邮件将ActionMailer::Base.deliveries作为Mail::Message实例插入到全局数组中.您可以从测试用例中读取该内容,并确保电子邮件符合预期.看到这里.

  • 谢谢.我花了一些时间来理解它,但现在我收到了最后一封邮件`email = ActionMailer :: Base.deliveries.last`,之后我可以使用`email`来测试[Email Spec](https:/ /github.com/bmabey/email-spec). (5认同)
  • `ActionMailer::Base.deliveries` 对我来说总是空的。我有一个 Rails 6 项目,没有配置 ActiveJob 或 ActionMailer。按照 ActionMailer 指南设置了一个示例,然后就到这里了。我使用“enqueued_jobs”代替此处建议的:/sf/answers/2882631741/ (2认同)

Den*_*nis 22

配置您的测试环境以累积发送的邮件ActionMailer::Base.deliveries.

# config/environments/test.rb
config.action_mailer.delivery_method = :test
Run Code Online (Sandbox Code Playgroud)

然后这样的事情应该允许你测试邮件是否被发送.

# Sample parameters you would expect for POST #create.
def reservation_params
  { "reservation" => "Drinks for two at 8pm" }
end

describe MyController do
  describe "#create" do
    context "when a reservation is saved" do
      it "sends a confirmation email" do
        expect { post :create, reservation_params }.to change { ActionMailer::Base.deliveries.count }.by(1)
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,我的示例使用RSpec 3语法.


Jul*_*and 19

我知道我迟到了这个,但对于未来的Google员工......

我认为更好的解决这个问题的回答在这里

之前接受的答案是测试Mailer本身(在控制器规范内).所有你应该在这里测试的是,梅勒被告知要提供具有正确参数的东西.

然后,您可以在其他地方测试Mailer,以确保它正确响应这些参数.

ReservationMailer.should_receive(:confirm_email).随着(an_instance_of(预约))

  • 例如,您可能想要检查在控制器或模型中发生某些事情时是否没有发送电子邮件。在这种情况下,您仍然必须使用`ActionMailer::Base.deliveries`。这不是不同意,只是作为这个答案的附录。 (2认同)

bob*_*lin 6

这是测试使用正确参数调用 Mailer 的方法。您可以在功能、控制器或邮件程序规范中使用此代码:

delivery = double
expect(delivery).to receive(:deliver_now).with(no_args)

expect(ReservationMailer).to receive(:confirm_email)
  .with('reservation')
  .and_return(delivery)
Run Code Online (Sandbox Code Playgroud)


Alt*_*gos 5

作为记录,对于使用rspec 3.4和ActiveJob发送异步电子邮件的任何人,您可以使用以下方法进行检查:

expect {
  post :create, params
}.to have_enqueued_job.on_queue('mailers')
Run Code Online (Sandbox Code Playgroud)