\$\begingroup\$
\$\endgroup\$
How would you DRY up this RSpec code?
require "spec_helper"
describe InvoiceMailer do
let(:user) { create(:user) }
let(:student) { create(:student, user: user) }
let(:body) { "And I for one will join with anyone, don't care what color you are. As long as you want change this miserable condition that exists on this earth." }
subject(:mail) { InvoiceMailer.issue(student, body) }
describe "issue" do
subject(:mail) { InvoiceMailer.issue(student, body) }
it "renders the subject" do
expect(mail.subject).to eq "New Invoice!"
end
it "renders the receiver email" do
expect(mail.to).to eq [student.user.email]
end
it "renders the sender email" do
expect(mail.from).to eq ["[email protected]"]
end
end
describe "rescind" do
subject(:mail) { InvoiceMailer.rescind(student, body) }
it "renders the subject" do
expect(mail.subject).to eq "Invoice Rescinded!"
end
it "renders the receiver email" do
expect(mail.to).to eq [student.user.email]
end
it "renders the sender email" do
expect(mail.from).to eq ["[email protected]"]
end
end
end
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Feb 24, 2014 at 13:59
1 Answer 1
\$\begingroup\$
\$\endgroup\$
3
You can use the its
syntax:
require "spec_helper"
describe InvoiceMailer do
let(:user) { create(:user) }
let(:student) { create(:student, user: user) }
let(:body) { "And I for one will join with anyone, don't care what color you are. As long as you want change this miserable condition that exists on this earth." }
describe "issue" do
subject { InvoiceMailer.issue(student, body) }
its(:subject) { should eq "New Invoice!" }
its(:to) { should eq [student.user.email] }
its(:from) { should eq ["[email protected]"] }
end
describe "rescind" do
subject { InvoiceMailer.rescind(student, body) }
its(:subject) { should eq "Invoice Rescinded!" }
its(:to) { should eq [student.user.email] }
its(:from) { should eq ["[email protected]"] }
end
end
You can further DRY it up using example groups
describe InvoiceMailer do
let(:user) { create(:user) }
let(:student) { create(:student, user: user) }
let(:body) { "And I for one will join with anyone, don't care what color you are. As long as you want change this miserable condition that exists on this earth." }
shared_examples_for "outgoing mail" do |method, mail_subject|
subject { InvoiceMailer.send(method, student, body) }
its(:subject) { should eq mail_subject }
its(:to) { should eq [student.user.email] }
its(:from) { should eq ["[email protected]"] }
end
describe "issue" do
it_should_behave_like "outgoing mail", :issue, 'New Invoice!'
end
describe "rescind" do
it_should_behave_like "outgoing mail", :rescind, 'Invoice Rescinded!'
end
end
answered Feb 24, 2014 at 17:16
-
\$\begingroup\$ Thanks for this answer! I don't usually like
its
but in this case it's very readable. I feel like there is still a lot of duplication between the theissue
andrescind
describe blocks though. The only differences between the two are the methods onInvoiceMailer
and the subject. Any thoughts? \$\endgroup\$niftygrifty– niftygrifty2014年02月25日 02:34:07 +00:00Commented Feb 25, 2014 at 2:34 -
\$\begingroup\$ Added an option with example groups \$\endgroup\$Uri Agassi– Uri Agassi2014年02月25日 07:15:17 +00:00Commented Feb 25, 2014 at 7:15
-
\$\begingroup\$ Oh! That's exactly what I was looking for! \$\endgroup\$niftygrifty– niftygrifty2014年02月25日 11:49:25 +00:00Commented Feb 25, 2014 at 11:49
lang-rb