9

I'm using the geocoder gem to add geocoding functionality to one of my Active Record model classes. This works great, but I don't actually want the geocoding to fire during unit tests.

I've tried stubbing out the call to geocode by adding this to my RSpec test:

before(:each) do
User.stub!(:geocode).and_return([1,1]) end

However, when I run my tests it still appears to be calling out to geocode. What am I doing wrong?

FYI, this all works if I stub on the instance level (e.g. some_user.stub! instead of User.stub!).

Kevin Pang
  • 41,172
  • 38
  • 121
  • 173

2 Answers2

9

If you want to use stubbing on the instance level, you should use other mocking framework than RSpec’s. It's mocha for example (add the following to spec/spec_helper.rb):

Spec::Runner.configure do |config|
  config.mock_with :mocha
end

http://rspec.info/documentation/mocks/other_frameworks.html

Now, you can use any_instance in your tests:

before(:each) do
 User.any_instance.stub(:geocode).and_return([1,1]) 
end
Vasiliy Ermolovich
  • 24,459
  • 5
  • 79
  • 77
  • 2
    This works if you only care about the return value of :geocode. But the geocoder module actually updates the latitude and longitude of the object. How would I stub that out? – harrism Feb 07 '12 at 12:25
  • In fact, the code you gave works with RSpec >= 2.6, but not with Mocha. – declan May 21 '12 at 18:45
  • @harrism a little late, but I decided to approach it like this, stubbing latitude and longitude in addition to the main geocode method: `Restaurant.any_instance.stub(:geocode).and_return([1, 1])` `Restaurant.any_instance.stub(:latitude).and_return(1)` `Restaurant.any_instance.stub(:longitude).and_return(1)` – shedd Apr 18 '14 at 17:04
3

it's

before(:each) do 
  Address.any_instance.stubs(:geocode).returns([1,1])
end

with mocha.