Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec: stub method call for external object inside method

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!

like image 866
Sly Avatar asked Oct 06 '22 19:10

Sly


1 Answers

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.

like image 132
Chris Salzberg Avatar answered Oct 10 '22 02:10

Chris Salzberg