【问题标题】:Rails 5 - testing the application mailerRails 5 - 测试应用程序邮件
【发布时间】:2017-03-29 17:17:04
【问题描述】:

我想在我的应用程序中测试邮件程序,以确保它正在执行我希望它执行的操作。

class LessonMailer < ApplicationMailer
   def send_mail(lesson)
      @lesson = lesson
      mail(to: lesson.student.email, 
        subject: 'A lesson has been recorded by your tutor')
   end
end 

这是我在 spec/mailers 目录中的测试

require "rails_helper"

RSpec.describe LessonMailer, :type => :mailer do
   describe "lesson" do

     let( :student ){ FactoryGirl.create :user, role: 'student', givenname: 'name', sn: 'sname', email: 'test@sheffield.ac.uk' }
     let( :lesson  ){ FactoryGirl.create :lesson, student_id: 2 }
     let( :mail    ){ LessonMailer.send_mail( lesson ).deliver_now 

     it "renders the headers" do
      expect(mail.subject).to eq("A lesson has been recorded")
      expect(mail.to).to eq(["to@example.ac.uk"])
      expect(mail.from).to eq(["no-reply@example.ac.uk"])
     end

    it "renders the body" do
     expect(mail.body.encoded).to match("A lesson form has been recorded")
    end
  end
end

我想测试“send_mail”方法是否按我想要的方式工作,但是,我收到了这个错误。我该如何解决这个问题?谢谢。

 NoMethodError:
   undefined method `email' for nil:NilClass
 # ./app/mailers/lesson_mailer.rb:4:in `send_mail'

【问题讨论】:

    标签: ruby-on-rails rspec ruby-on-rails-5 factory-bot


    【解决方案1】:

    因此,使用 FactoryGirl,您只需实例化所需的不同对象。阅读您的代码,很明显lesson 有一个student,而学生有一个email。所以继续创建你需要的一切,然后调用你的方法。你可以这样做:

    # Here's the student factory (for this use case, you'll probably want to make it more general)
    FactoryGirl.define do
      factory :user do
        role 'student'
        givenname 'name'
        sn 'sname'
        email 'test@sheffield.ac.uk'
      end
    end
    
    # Here's your test
    require "rails_helper"
    
    RSpec.describe LessonMailer, :type => :mailer do
      describe "lesson" do
        let( :student ){ create :student, email: 'test_email@example.com' }
        let( :lesson  ){ create :lesson, student: student }
        let( :mail    ){ LessonMailer.send_mail( lesson ) }
    
        it ' ... ' do
          ...
        end
      end
    end
    

    您需要让test 环境知道您希望将电子邮件传送到 ActionMailer::Base.deliveries 数组。为此,请确保

    config.action_mailer.delivery_method = :test
    

    在您的config/environments/test.rb中设置

    最后一件事,我不确定您是否需要它,但您可能需要通过.deliver_now 给邮件发件人打电话。

    像这样:

    let( :mail ){ LessonMailer.send_mail( lesson ).deliver_now }
    

    ... 否则它可能无法发送。我不记得顶部了。

    告诉我进展如何。

    【讨论】:

    • 感谢您的回复,但是当我实施您的解决方案时出现错误。 NoMethodError: undefined method email' for nil:NilClass # ./app/mailers/lesson_mailer.rb:4:in send_mail' 我该如何解决这个问题谢谢。
    • 你们有工厂实施吗?你有一个student 工厂和email 属性吗? NilClass 错误很有趣,因为这意味着您没有尝试调用 .emailstudent。因此,我们需要确保学生被实例化并且它具有email 属性。这里是创建工厂的参考:github.com/brennovich/cheat-ruby-sheets/blob/master/…
    • 感谢您的帮助。我终于设法解决了。我使用 student_id 为课程设置工厂的方式是问题所在。
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2014-10-05
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2020-09-22
    相关资源
    最近更新 更多