5

I'm attempting to stub the behavior of a method within a method:

class A
  def method_one(an_argument)
  begin
    external_obj = ExternalThing.new
    result = external_obj.ext_method(an_argument)
  rescue Exception => e
    logger.info(e.message)
  end
  end
end

Spec:

it "should raise an Exception when passed a bad argument" do
  a = A.new
  external_mock = mock('external_obj')
  external_mock.stub(:ext_method).and_raise(Exception)
  expect { a.method_one("bad") }.to raise_exception
end

However, an Exception never gets raised.

I've also tried:

it "should raise an Exception when passed a bad argument" do
  a = A.new
  a.stub(:ext_method).and_raise(Exception)
  expect { a.method_one("bad") }.to raise_exception
end

and that doesn't work either. How can one properly stub the external method to force an Exception in this case?

Thanks in advance for any ideas!

Sly
  • 743
  • 13
  • 38

1 Answers1

5

You have to stub the class method new of ExternalThing and make it return the mock:

it "should raise an Exception when passed a bad argument" do
  a = A.new
  external_obj = mock('external_obj')
  ExternalThing.stub(:new) { external_obj }
  external_obj.should_receive(:ext_method).and_raise(Exception)
  expect { a.method_one("bad") }.to raise_exception
end

Note that this solution is deprecated in rspec 3. For solution not deprecated in rspec 3 see rspec 3 - stub a class method.

Community
  • 1
  • 1
Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
  • Beautiful. @shioyama - that was exactly what was missing. I'd been pounding my head on that one for too long! Thank you, thank you, thank you! – Sly Aug 27 '12 at 22:09