Лучший способ протестировать почтовую программу с аргументами

У меня есть почтовая программа, которая передает такой аргумент:

AnimalMailer.daily_message(owner).deliver_later

Метод выглядит следующим образом:

AnimalMailer

class AnimalMailer < ApplicationMailer

  def daily_message(owner)
     mail(
      to: "#{user.name}",
      subject: "test",
      content_type: "text/html",
      date: Time.now.in_time_zone("Mountain Time (US & Canada)")
    )
  end
end

Я новичок в написании спецификаций, и мне было интересно, как мне передать владельца методу и протестировать его. У меня сейчас такая установка:

require "rails_helper"

RSpec.describe AnimalMailer, type: :mailer do
  
  describe "monthly_animal_message" do
    let(:user) { create(:user, :admin) }

    it "renders the headers" do
      expect(mail.subject).to eq("test")
      expect(mail.to).to eq(user.name)
    end
  end
end

person lost9123193    schedule 28.07.2020    source источник


Ответы (2)


Спецификации обычно состоят из трех шагов: 1) настройка, 2) вызов, 3) ожидание. Это относится к почтовым программам модульного тестирования, как и ко всему остальному. Вызов и параметры в тесте такие же, как и для общего использования, поэтому в вашем случае:

RSpec.describe AnimalMailer, type: :mailer do  
  describe "monthly_campaign_report" do
    let(:user) { create(:user, :admin) }
    let(:mail) { described_class.daily_message(user) }  # invocation

    it 'renders the headers' do
      expect(mail.subject).to eq('test')
      expect(mail.to).to eq(user.name)
    end

    it 'renders the body' do
      # whatever
    end
  end
end

Обратите внимание, что поскольку describe — это имя тестируемого класса, вы можете использовать described_class оттуда, чтобы вернуться к описанному классу. Вы всегда можете использовать AnimalMailer.daily_message, но среди прочего described_class гарантирует, что если вы перетасовываете или делитесь примерами, вы всегда проверяете то, что вы думаете.

Также обратите внимание, что в случае модульного тестирования почтовой программы вы в основном сосредоточены на правильной генерации контента. Тестирование успешной доставки или использования в заданиях, контроллерах и т. д. будет выполняться как часть тестов запросов или функций.

person rmlockerd    schedule 29.07.2020
comment
Благодарность! Я решил это, но только что увидел это решение и в итоге сделал что-то очень похожее на это. - person lost9123193; 29.07.2020

Прежде чем тестировать его, убедитесь, что файл config / environment / test.rb установлен на:

  config.action_mailer.delivery_method = :test

Это гарантирует, что электронные письма на самом деле не отправляются, а сохраняются в массиве ActionMailer :: Base.deliveries.

После четырехэтапного теста:

animal_mailer.rb

class AnimalMailer < ApplicationMailer
  default from: 'noreply@animal_mailer.com'

  def daily_message(owner)
    @name = owner.name

    mail(
      to: owner.email,
      subject: "test",
      content_type: "text/html",
      date: Time.now.in_time_zone("Mountain Time (US & Canada)")
    )
  end
end

animal_mailer_spec.rb

RSpec.describe AnimalMailer, type: :mailer do
  describe 'instructions' do
    let(:user) { create(:user, :admin) }
    let(:mail) { described_class.daily_message(user).deliver_now }

    it 'renders the subject' do
      expect(mail.subject).to eq("test")
    end

    it 'renders the receiver email' do
      expect(mail.to).to eq([user.email])
    end

    it 'renders the sender email' do
      expect(mail.from).to eq(['noreply@animal_mailer.com'])
    end

    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end
  end
end

если у вас есть модельный пользователь:

class User
  def send_instructions
    AnimalMailer.instructions(self).deliver_now
  end
end


RSpec.describe User, type: :model do
  subject { create :user }

  it 'sends an email' do
    expect { subject.send_instructions }
      .to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end
person Ewerton    schedule 29.07.2020