rspec邮件程序测试,对象传递给邮件方法

时间:2016-12-15 14:02:22

标签: ruby-on-rails rspec mailer

我的rails应用程序发送电子邮件,邮件程序方法需要传入对象,如下面的evidence_added_email方法代码所示:

class EvidenceMailer < ApplicationMailer
include Rails.application.routes.url_helpers

def evidence_added_email(evidence, current_user, root_url)
  @evidence = Evidence.find(evidence)
  @root_url = root_url
  recipients = User.where(is_auditor: true).map {|u| u.email }
  blind_copy_recipients = User.where(receive_notifications: true).map {|u| u.email }
  subject = 'SGPLAN: Evidência de ' + @evidence.milestone.manager.user_name + ' adicionada'
  mail(to: recipients, bcc: blind_copy_recipients, from: current_user.email, subject: subject)
end

def test_email
  mail(to: 'to@example.com', from: 'from@example.com', subject: 'Test Subject')
end

传入的证据参数/对象需要创建许多其他对象。所以测试规范看起来像这样:

require 'rails_helper'

RSpec.describe EvidenceMailer, type: :mailer do
  FactoryGirl.create(:admin_user)
  Agency.current = Agency.find_by(initials: 'SECTI').id
  FactoryGirl.create(:department)
  FactoryGirl.create(:first_plan)
  Plan.current = Plan.find_by(name: 'first').id
  FactoryGirl.create(:project)
  FactoryGirl.create(:milestone)
  FactoryGirl.create(:evidence)

  describe "evidence added email" do
    let(:mail) { EvidenceMailer.evidence_added_email(Evidence.find_by(name: 'Test Evidence').id,
                                                     User.find_by(email: 'admin@example.com'),
                                                     '/test_root_url') }
    it "renders the headers" do
      expect(mail.subject).to include("SGPLAN")
    end
  end

  describe "test email" do
    let(:mail) { EvidenceMailer.test_email }
    it "renders the headers" do
      expect(mail.subject).to eq('Test Subject')
    end
  end
end

测试电子邮件示例已通过,但添加的证据示例失败,并显示以下错误:

1) EvidenceMailer evidence added email renders the headers
     Failure/Error:
       let(:mail) { EvidenceMailer.evidence_added_email(Evidence.find_by(name: 'Test Evidence').id,
                                                        User.find_by(email: 'admin@example.com'),
                                                        '/test_root_url') }

     NoMethodError:
       undefined method `id' for nil:NilClass
     # ./spec/mailers/evidence_notifications_spec.rb:14:in `block (3 levels) in <top (required)>'
     # ./spec/mailers/evidence_notifications_spec.rb:18:in `block (3 levels) in <top (required)>'

如果我通过使用调试器单步执行spec文件,似乎每次执行describe循环两次。第一次执行它们时,Evidence对象和所有其他对象都存在但不执行EvidenceMailer方法。第二次对象不再存在但执行了EvidenceMailer.test_email方法并且该测试通过了。

我对使用rspec进行rails和测试相对较新,并且没有找到任何需要将参数传递到邮件程序方法的rspec测试示例。我们正在为我们的应用程序的某些部分改进测试,并且我知道evidence_added_email功能确实有效。

我们的环境如下:

capybara (2.7.1)
poltergeist (1.6.0)
database_cleaner (1.5.3)
factory_girl_rails (4.7.0)
rails (4.2.5)
rspec-core (3.5.4)
rspec-expectations (3.5.0)
rspec-mocks (3.5.0)
rspec-rails (3.5.2)
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
postgresql

有人可以建议我如何让这个测试工作吗?

更新

证据工厂如下:

FactoryGirl.define do
  factory :evidence do
    name 'Test Evidence'
    before(:create) do |evidence|
      evidence.milestone = Milestone.find_or_create_by(title: 'Test Milestone')
      evidence.plan = Plan.find_or_create_by(name: 'first')
      evidence.agency = Agency.find_or_create_by(initials: 'SECTI')
    end
  end
end

我添加了一些输出语句如下:

require 'rails_helper'

RSpec.describe EvidenceMailer, type: :mailer do
  ...
  puts "First #{Evidence.find_by(name: 'Test Evidence').id}"

  describe "evidence added email" do
    puts "Second #{Evidence.find_by(name: 'Test Evidence').id}"
    ...
  end

  describe "test email" do
    puts "Third #{Evidence.find_by(name: 'Test Evidence').id}"
    ...
  end
end

在控制台上显示以下结果

First 1
Second 1
Third 1
F.

Failures:

  1) EvidenceMailer evidence added email renders the headers
     Failure/Error:
       let(:mail) {    EvidenceMailer.evidence_added_email(Evidence.find_by(name: 'Test Evidence').id,
                                                        User.find_by(email: 'admin@example.com'),
                                                        '/test_root_url') }

     NoMethodError:
       undefined method `id' for nil:NilClass
     # ./spec/mailers/evidence_notifications_spec.rb:16:in `block (3 levels) in <top (required)>'
     # ./spec/mailers/evidence_notifications_spec.rb:20:in `block (3 levels) in <top (required)>'

所以Evidence.find_by在一个地方成功,但在另一个地方没有成功。

0 个答案:

没有答案
相关问题