Тестирование многострочных писем ActionMailer с помощью RSpec
в настоящее время я тестирую свои почтовые программы с помощью RSpec, но я начал настраивать составные электронные письма, как описано в руководствах Rails здесь: http://guides.rubyonrails.org/action_mailer_basics.html#sending-multipart-emails
У меня есть шаблоны почтовых отправителей в текстовом и html-форматах, но похоже, что мои тесты проверяют только часть HTML. Есть ли способ проверить текстовый шаблон отдельно?
Это только проверка представления HTML, потому что это первый в порядке по умолчанию?
4 ответов
чтобы дополнить отличный ответ nilmethod, вы можете очистить свои спецификации, Протестировав как текстовые, так и html-версии, используя общую группу примеров:
spec_helper.rb
def get_message_part (mail, content_type)
mail.body.parts.find { |p| p.content_type.match content_type }.body.raw_source
end
shared_examples_for "multipart email" do
it "generates a multipart message (plain text and html)" do
mail.body.parts.length.should eq(2)
mail.body.parts.collect(&:content_type).should == ["text/plain; charset=UTF-8", "text/html; charset=UTF-8"]
end
end
your_email_spec.rb
let(:mail) { YourMailer.action }
shared_examples_for "your email content" do
it "has some content" do
part.should include("the content")
end
end
it_behaves_like "multipart email"
describe "text version" do
it_behaves_like "your email content" do
let(:part) { get_message_part(mail, /plain/) }
end
end
describe "html version" do
it_behaves_like "your email content" do
let(:part) { get_message_part(mail, /html/) }
end
end
Это можно проверить с помощью регулярных выражений.
поиск вещей в HTML-части (используйте #после этого, чтобы соответствовать):
mail.body.parts.find {|p| p.content_type.match /html/}.body.raw_source
поиск вещей в текстовой части (используйте #после этого, чтобы соответствовать):
mail.body.parts.find {|p| p.content_type.match /plain/}.body.raw_source
проверка того, что он действительно генерирует составное сообщение:
it "generates a multipart message (plain text and html)" do
mail.body.parts.length.should == 2
mail.body.parts.collect(&:content_type).should == ["text/html; charset=UTF-8", "text/plain; charset=UTF-8"]
end
чтобы сделать вещи еще проще, вы можете использовать
message.text_part and
message.html_part
, чтобы найти соответствующие части. Это работает даже для структурированных составных / альтернативных сообщений с вложениями. (Протестировано на Ruby 1.9.3 с Rails 3.0.14.)
эти методы используют некоторую эвристику, чтобы найти соответствующие части сообщения, поэтому, если ваше сообщение имеет несколько текстовых частей (например, как Apple Mail создает их), это может не сделать "правильную вещь".
это изменило бы вышеуказанный метод к
def body_should_match_regex(mail, regex)
if mail.multipart?
["text", "html"].each do |part|
mail.send("#{part}_part").body.raw_source.should match(regex)
end
else
mail.body.raw_source.should match(regex)
end
end
который работает как для текстовых (не-составных) сообщений, так и для составных сообщений и проверяет все тела сообщений на определенное регулярное выражение.
Теперь, есть добровольцы, чтобы сделать "настоящий" RSpec matcher из этого? :) Что-то вроде
@mail.bodies_should_match /foobar/
было бы намного лучше ...
если ваша электронная почта имеет вложения, текст и html-части будут помещены в multipart/alternative
часть. Это отмечается в разделе отправка писем с вложениями в руководство Rails 3.
чтобы справиться с этим, я сначала упростил get_message_part
способ выше:
def get_message_part(mail, content_type)
mail.body.parts.find { |p| p.content_type.match content_type }
end
тогда в моем тесте:
multipart = get_message_part(email, /multipart/)
html = get_message_part(multipart, /html/)
html_body = html.body.raw_source
assert_match 'some string', html_body