У меня была сессия парного программирования с более опытным моим коллегой, и вместе мы нашли следующее решение.
Сначала мы определили некоторое общее поведение:
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
и тогда тесты станут более читабельными!
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
и мы также извлекли следующий метод
def send_a_test_envelope_to(distributor)
@envelope = Factory(:envelope, :destination => '32495xxxxxx', :message => "Message sent by #{@distributor.name}")
@envelope.send_to(distributor)
end
Теперь я все еще могу применить предложенный ответ, предложенный @Taryn, но я не совсем уверен, что он действительно нужен больше.