che*_*ell 3 ruby ruby-on-rails-4
我正在为我的应用程序创建测试。
创建 quote_request 后,我会向用户发送一封确认电子邮件。我还发了一封电子邮件通知校对人员。
我仍在学习 Ruby,我确信有更好的方法来编写以下代码:
def email_exists?(email_address)
ActionMailer::Base.deliveries.each do |m|
if m[:to].to_s == email_address
return true
end
end
end
def email_with_subject_exists?(email_address, email_subject)
ActionMailer::Base.deliveries.each do |m|
if m[:to].to_s == email_address && m[:subject].to_s == email_subject
return true
else
return false
end
end
end
Run Code Online (Sandbox Code Playgroud)
我发现,如果我不包含 return false,那么由于某种原因,电子邮件的全部内容都会输出。
任何改进此代码的帮助将不胜感激。
以下是 ActionMailer::Base.deliveries 的内容:
[#<Mail::Message:70094817191440, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: peterjohnson1@example.com>, <Message-ID: <57c7ebdb1b5f4_2ab93fc03545e1f850559@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Welcome to the ProvenWord team!>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdb16e49_2ab93fc03545e1f85046d"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>, #<Mail::Message:70094829223120, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: peterjohnson2@example.com>, <Message-ID: <57c7ebdb23188_2ab93fc03545e1f850725@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Welcome to the ProvenWord team!>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdb229aa_2ab93fc03545e1f8506be"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>, #<Mail::Message:70094772574660, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: peterjohnson3@example.com>, <Message-ID: <57c7ebdb28936_2ab93fc03545e1f850960@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Welcome to the ProvenWord team!>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdb27bf6_2ab93fc03545e1f850835"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>, #<Mail::Message:70094829778220, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: peterjohnson4@example.com>, <Message-ID: <57c7ebdb2c982_2ab93fc03545e1f85116b@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Welcome to the ProvenWord team!>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdb2c064_2ab93fc03545e1f85104b"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>, #<Mail::Message:70094829991680, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: peterjohnson5@example.com>, <Message-ID: <57c7ebdb30c2b_2ab93fc03545e1f85135c@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Welcome to the ProvenWord team!>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdb30465_2ab93fc03545e1f85123c"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>, #<Mail::Message:70094777280260, Multipart: true, Headers: <Date: Thu, 01 Sep 2016 15:50:35 +0700>, <From: from@example.com>, <To: johnpeters@example.com>, <Message-ID: <57c7ebdbb8421_2ab93fc03545e1f8515e5@Mitchell-Goulds-MacBook-Air.local.mail>>, <Subject: Your ProvenWord quotation request has been delivered>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_57c7ebdbb76fa_2ab93fc03545e1f8514ee"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>]
Run Code Online (Sandbox Code Playgroud)
我通常这样做(这是用RSpec)
it "sends correct email" do
UserMailer.welcome_email(user).deliver
ActionMailer::Base.deliveries.last.tap do |mail|
expect(mail.from).to eq(["myapp@awesome.com"])
expect(mail.subject).to eq("Welcome #{user.name}")
end
end
Run Code Online (Sandbox Code Playgroud)
编辑:
有几种方法可以做到这一点。我个人喜欢将发送内容和消息包含内容之间的逻辑分开。
控制器(最好)/模型(可能)动作是这样的:
def something
Mailer.a(item).deliver
Mailer.b(item).deliver
end
Run Code Online (Sandbox Code Playgroud)
测试发送正确的电子邮件:
it "sends correct number of emails" do
expect do
## Trigger your stuff here (#something above)
end.to change{ ActionMailer::Base.deliveries.size }.by(2)
end
Run Code Online (Sandbox Code Playgroud)
EDIT2: ^^this^^ 实际上不会测试是否发送了正确的两封电子邮件。为此,你可以做类似的事情ActionMailer::Base.deliveries.map{|e| e[:subject]}.sort == ["asubject", "bsubject"].sort,但是当你改变主题时,这就很脆弱了。由您决定在这里做什么/测试。(也看起来像assert Mailer.recieves(:a).with(obj)(我忘记了确切的语法,我不知道你正在使用什么测试框架,但它们都有类似的东西。)
测试邮件内容是否正确
it "Mailer#a has correct email content" do
Mailer.a(user).deliver
ActionMailer::Base.deliveries.last.tap do |mail|
expect(mail.from).to eq(["myapp@awesome.com"])
expect(mail.subject).to eq("Welcome #{user.name}")
end
end
## repeat for Mailer#b
Run Code Online (Sandbox Code Playgroud)