【问题标题】:How can I test a custom mailer?如何测试自定义邮件程序?
【发布时间】:2014-09-12 03:34:37
【问题描述】:

我正在尝试通过 Rails 测试后续电子邮件的功能,我希望在用户通过电子邮件将 url 书签地址发送到 mailgun(我已经测试并且正在工作)之后发送该邮件。我不确定我的邮件程序代码是否设置正确,但是当我向 mailgun 发送电子邮件时没有发送后续电子邮件。

这是我的自定义邮件:

<!DOCTYPE html>
<html>
  <head>
    <meta content= 'text/html; charset=UTF-8' http-equiv='Content-Type' />
      </head>
      <body>
        <h1>Hi <%= @user.name %>,</h1>
        <p>
          This is just a friendly email to let you know the following bookmark was saved:
        </p>
        <p>
          <%= @bookmark.url %>
        </p>
      <p>
        Cheers! <br/>
        Bookmarks.com
      </p>
    </body>
    </html>

这是我传入的控制器代码:

class IncomingController < ApplicationController
skip_before_filter :verify_authenticity_token
  def create
    Rails.logger.info "INCOMING PARAMS HERE: #{params}"
    Rails.logger.info "Topics: #{params[:subject]}"
    Rails.logger.info "Url: #{params['stripped-text']}"
    Rails.logger.info "User email: #{params[:sender]}"
    user = User.find_by_email(params[:sender])
    Rails.logger.info "@@@@@@@@@@@@@@@@ User: #{user.inspect}"
    if user
      @bookmark = Bookmark.new(url: params['stripped-text'])
      topics = []
      topic_names = params[:subject].split(' ')
      topic_names.each do |topic_name|
        name = topic_name.sub(/#/, '')
        topics << Topic.find_or_create_by_name(name)
      end
      if @bookmark.save
        topics.each do |topic| 
          @bookmark.topics << topic
        end
        user.bookmarks << @bookmark
        FollowUpMailer.notify(@bookmark).deliver
      end
    end    
    head 200 
  end
end

这是我创建 url 书签的代码:

def create
    @bookmark = Bookmark.new(bookmark_params)
    @bookmark.user = current_user
    if @bookmark.save
      topic_names = params[:topic_names]
      topic_names = topic_names.split(' ')
      topic_names.each do |topic_name|
        name = topic_name.sub(/#/, '')
        topics << Topic.find_or_create_by_name(name)
      end
      respond_to do |format|
        format.html { redirect_to @bookmark, notice: 'Bookmark was successfully created.' }
        format.json { render action: 'show', status: :created, location: @bookmark }
      end
    else
      respond_to do |format|
        format.html { render action: 'new' }
        format.json { render json: @bookmark.errors, status: :unprocessable_entity }
      end
    end   
  end

我对此进行测试的唯一方法是通过 mailgun 通过生产发送电子邮件并查看我的本地 Rails 服务器日志(没有显示任何操作迹象),所以我不知道如何测试本地邮件程序正在开发中,因为我还是编程新手。我能得到一些关于如何测试以解决一些错误的想法吗?谢谢!

问题编辑: 我忘了添加我的 follow_up_mailer.rb 代码:

class FollowUpMailer < ActionMailer::Base
  default from: "valeriemettler@gmail.com"

  def notify(bookmark)
    @bookmark = bookmark

    mail(to: user.email, subject: 'Your bookmark was saved!')
  end
end

这是我用 FollowUpMailer.notify(Bookmark.first).deliver 测试后得到的错误:

2.0.0-p481 :001 > FollowUpMailer.notify(Bookmark.first)deliver
SyntaxError: (irb):1: syntax error, unexpected tIDENTIFIER, expecting end-of-input
from /home/vagrant/.rvm/rubies/ruby-2.0.0-p481/bin/irb:12:in `<main>'

有什么想法吗?

【问题讨论】:

  • 在我看来,错误在于您没有在 Mailer 方法中初始化 @user 变量,尽管您在视图中引用了它。我认为定义该变量将解决该(一个)错误。不过,下面的一般测试提示仍然适用。您可以直接在控制台(本地)中测试邮件程序,而无需点击该控制器。
  • Valerie -- 这只是一个错字(语法错误 == 错字)。 deliver 是一个方法,所以在它之前需要一个.FollowUpMailer.notify(Bookmark.first).deliver
  • @Sasha--感谢您发现错字!当我在 Mailer 方法中初始化实例变量 user 然后在控制台中对其进行测试时,无论是否初始化用户变量,它都会返回相同的结果:NameError: uninitialized constant FollowUpMailer。有什么想法吗? :)
  • 您的 Rails 控制台是否打开了很长时间?您可能只需要关闭并重新打开它。这似乎是最有可能的,除非你在生产控制台或其他东西中。

标签: ruby-on-rails actionmailer mailgun


【解决方案1】:

在其余答案之前快速说明。当您在 Production 上发送/接收消息时,您的本地服务器不应显示任何内容。您应该查看您的生产服务器日志 (heroku logs) 以查看工作/错误。但是,我认为这不是最好的测试方法,所以我的完整答案如下...

一个邮件程序在 Rails 中需要几个部分。您拥有其中的大部分,但您似乎缺少 Mailer 类——即FollowUpMailer

该文件应该在app/mailers/follow_up_mailer.rb 中,并且它应该定义一个notify 方法,当您在控制器中运行该行代码时调用该方法。

查看有关该主题的Rails Guide,了解该方法应该是什么样子、如何将变量传递给视图、视图应该命名什么以及它的位置。

更一般地说,我建议尝试将其中的一些逻辑移动到书签模型中。这似乎无关紧要,但它会让你的生活更轻松。如果您将邮件行为与控制器分离,您可以更轻松地直接测试邮件。

也许在 Bookmark 类上创建一个save_and_notify 方法,如果它不返回 true,则在控制器中抛出一个错误。该方法将包含您操作的最后几行:

    topics.each do |topic| 
      @bookmark.topics << topic
    end
    user.bookmarks << @bookmark
    FollowUpMailer.notify(@bookmark).deliver

它还必须将topicsuser 作为参数。

有多种方法可以将其中的一些逻辑移入模型中。那只是一个。完成此操作后,您可以更轻松地从 Rails 控制台测试书签保存和消息发送,或者也为它编写测试。

请注意,您现在也可以直接在控制台中测试邮件。只需这样做:FollowUpMailer.notify(Bookmark.first).deliver。发送时遇到的任何错误都应在控制台中提出。不过请务必设置消息拦截器,否则,您将在测试时发送实时消息。


要修复邮件程序中的一个错误,您需要在 notify 方法中定义一个 @user 变量。该变量在邮件程序视图中使用,但未在其关联方法中定义(基本上是邮件程序的控制器操作)。或者,您可以从视图@bookmark.user.name 中的书签推断用户。无论哪种方式,请尝试在本地控制台中对此进行测试,您将立即获得有关它是否正常工作的反馈。

【讨论】:

  • 谢谢,@Sasha!我忘了在我的问题中添加我的 follow_up_mailer.rb。这会以任何方式改变您的建议吗?我还将按照您的建议添加运行 FollowUpMailer.notify(Bookmark.first).deliver 时遇到的错误。
猜你喜欢
  • 2013-01-24
  • 2015-02-14
  • 2012-03-04
  • 2014-10-05
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 2013-04-12
相关资源
最近更新 更多