I had a pair programming session with a more experienced colleague, and together we came to the next solution.
First, we defined some common behavior:
subject {@envelope} let(:the_sent_message){ @envelope.sent_messages.find_by_distributor_id(@distributor.id)} shared_examples_for "a typical sent envelope" do it{should have(1).sent_messages } it{should have(2).log_lines } end shared_examples_for "a successful delivery" do it("should have 1 IN_PROGRESS sms-message") { the_sent_message.should be_in_progress } it "should have 1 sms-message with external ref" do the_sent_message.external_message_id.should_not == nil end it "should log the delivery success" do @envelope.log_lines.last.message.should =~ /^Sent message/ end end shared_examples_for "a failing delivery" do it("should have 1 FAILED sms-message") { the_sent_message.should be_failed } it "should have 1 sms-message and no external ref" do the_sent_message.external_message_id.should == nil end it "should log the delivery failure" do @envelope.log_lines.last.message.should =~ /^Failed to send/ end end
and then the tests will become more readable!
context "delivered by d1" do before do @distributor = Distributor.find_by_name(Distributor::D1) send_a_test_envelope_to(@distributor) end it_should_behave_like "a typical sent envelope" it_should_behave_like "a successful delivery" end context "delivered by d2" do before do @distributor = Distributor.find_by_name(Distributor::D2) send_a_test_envelope_to(@distributor) end it_should_behave_like "a typical sent envelope" it_should_behave_like "a successful delivery" end
and we also extracted the following method
def send_a_test_envelope_to(distributor) @envelope = Factory(:envelope, :destination => '32495xxxxxx', :message => "Message sent by #{@distributor.name}") @envelope.send_to(distributor) end
Now I can apply the suggested answer @Taryn, but I'm not quite sure that I really need it more.
source share