On Nov 04, 2007, at 9:55 am, Mikel L. wrote:
end
Mikel,
It looks like you are doing too much here. You are specifying sending
with the SMTP object in the same block you are specifying the
algorithm for counting the sent emails. Also, the way it interrogates
the email object to extract data looks fragile. I would prefer to
make the Email object responsible for sending itself, although I will
await the approval of an expert before I tell you my solution is better!
I had a go at this, and my solution is MUCH longer, but it breaks the
behaviour down to a finer level. (As you didn’t show the code for
Mailer::Sender, I wrote a quick implementation myself, possibly
similar to yours.) Also, I’m never quite sure how best to use
“before” blocks, so don’t take mine as a canonical example. Anyway
here is what I came up with:
class Email
def initialize(encoded_message, from, destination)
@encoded_message, @from, @destination =
encoded_message, from, destination
end
def send_via(smtp)
begin
smtp.send_message(@encoded_message, @from, @destination)
rescue IOError => e
0
else
1
end
end
end
describe Email, :shared => true do
before(:each) do
@smtp = mock(“Net::SMTP”)
@email = Email.new(“message”, “from@mydomain”, “to@destination”)
end
it "send_via: should send :send_message to the SMTP object with
the email details" do
@smtp.should_receive(:send_message).
with(“message”, “from@mydomain”, “to@destination”)
@email.send_via(@smtp)
end
end
describe Email, “sent via a working SMTP” do
it_should_behave_like “Email”
before(:each) do
@smtp.stub!(:send_message)
end
it "send_via: should return 1 if the email sent successfully" do
@email.send_via(@smtp).should == 1
end
end
describe Email, “sent via a faulty SMTP” do
it_should_behave_like “Email”
before(:each) do
@smtp.stub!(:send_message).and_raise(IOError.new)
end
it "send_via: should return 1 if the email sent successfully" do
@email.send_via(@smtp).should == 0
end
end
class Spammer
def initialize(smtp)
@smtp = smtp
end
def send(emails)
emails.inject(0) { |success_count, email| success_count +
email.send_via(@smtp) }
end
end
describe Spammer, “created with an SMTP” do
before(:each) do
@email_successful_1 = mock(Email)
@email_successful_1.stub!(:send_via).and_return(1)
@email_successful_2 = mock(Email)
@email_successful_2.stub!(:send_via).and_return(1)
@email_unsuccessful_1 = mock(Email)
@email_unsuccessful_1.stub!(:send_via).and_return(0)
@emails = [ @email_successful_1, @email_successful_2,
@email_unsuccessful_1]
@spammer = Spammer.new(:smtp)
end
it "send: should send each email in turn with the SMTP and return
the successful count" do
@email_successful_1.should_receive(:send_via).with(:smtp).and_return(1)
@email_successful_2.should_receive(:send_via).with(:smtp).and_return(1)
@email_unsuccessful_1
.should_receive(:send_via).with(:smtp).and_return(2)
@spammer.send(@emails)
end
it "send: should return the count of successful emails" do
@spammer.send(@emails).should == 2
end
end
Let me know if this is helpful
Regards
Ashley
–
blog @ http://aviewfromafar.net/
linked-in @ http://www.linkedin.com/in/ashleymoran
currently @ home