首页 文章

使用RSpec测试ActionMailer多部分电子邮件

提问于
浏览
30

我已经开始设置多部分电子邮件,如Rails指南中所述:http://guides.rubyonrails.org/action_mailer_basics.html#sending-multipart-emails

我有文本和html格式的邮件模板,但看起来我的测试只检查HTML部分 . 有没有办法单独检查文本模板?

是否仅检查HTML视图,因为它是默认顺序中的第一个?

4 回答

  • 1

    为了补充,nilmethod的优秀答案,您可以通过使用共享示例组测试text和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
    
  • 27

    这可以使用正则表达式进行测试 .

    在HTML部分中查找内容(在此之后使用#should匹配):

    mail.body.parts.find {|p| p.content_type.match /html/}.body.raw_source
    

    在纯文本部分中查找内容(在此之后使用#should进行匹配):

    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
    
  • 23

    为了使事情变得更简单,您可以使用

    message.text_part    and
    message.html_part
    

    找到各自的部分 . 这适用于带附件的结构化多部分/备用消息 . (使用Rails 3.0.14在Ruby 1.9.3上测试过 . )

    这些方法使用某种启发式方法来查找相应的消息部分,因此如果您的消息有多个文本部分(例如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匹配器吗? :) 就像是

    @mail.bodies_should_match /foobar/
    

    会更好......

  • 32

    如果您的电子邮件包含附件,则文本和html部分将放在 multipart/alternative 部分中 . 这在Sending Emails with Attachments in the Rails 3 Guide下注明 .

    为了解决这个问题,我首先将上面的 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
    

相关问题