How to stub geocoder for use in cucumber tests

As I continue to work on FANZO, I occasionally run into something where google doesn’t help much. When this happens, I am forced to be creative to get something to work. I always wonder if there is a better way, so I thought I would post my latest kludge and see what others know that I don’t.

I’ve been using geocoder to help me get geospatial data for addresses when they are entered into our system.  I’ve also been enjoying using cucumber for BDD. To complicate things a bit more, I’m also using guard to auto run my tests, and I’m using spork to keep the framework bootstrapped so the tests run faster. However, my tests were still running slow. I figured, rightly, that I was making too many requests to the google maps api via geocoder, and that was slowing things down. So, how to fix it?

First, I had to address the problem in RSpec. Google helped me here. There is a gist here that adds a call you can use to mock all of the geocoding calls, and it warns you if you missed one. I found this very helpful, and I really sped up my RSpec tests.

Second, I had to address the problem in cucumber. The cucumber initialization works differently than RSpecs, and my first attempt at dropping in something similar to the RSpec fix just didn’t work. So, after the tests taking longer and longer I finally worked out a solution. I am including it here. Please let me know in the comments if you know a better way to accomplish this

In features/support/env.rb I put the following in the Spork.prefork

  require 'geocoder/results/base'

  class MockResult < ::Geocoder::Result::Base
    def initialize(data = [])
      super(data)
    end
  end

Also in features/support/env.rb I put the following in the Spork.each_run

  Before do
    options = {address1: 'address1', address2:'address2', coordinates:[1,2], state_id:1, postal_code:'98003', country_id:1 }

    MockResult.new.tap do |result|
      result.stub options
      ::Geocoder.stub :search => [result]
    end
  end

That was sufficient to mock the search call, which actually hits google maps, for each test. Hope this helps.

About Paul

Startup founder, father of 3 girls, Notre Dame alumnus, agile practitioner and tech enthusiast. I love building great companies to solve cool problems.
This entry was posted in BDD, Cucumber, RSpec, Ruby on Rails and tagged , , , . Bookmark the permalink.

2 Responses to How to stub geocoder for use in cucumber tests

  1. You might want to look into using VCR and Webmock (or fakeweb) to handle your cucumber tests. You get the additional benefit of being able to check periodically that the API hasn’t changed, and you test your code against a result that is ‘real’ from the boundary of your system.
    https://github.com/myronmarston/vcr
    https://github.com/bblimke/webmock

    • Paul says:

      Thanks Matt. I did look at those, and was quite impressed. At the time I wanted something a little lighter weight as I was in a hurry, but I’m hoping to spend some time integrating VCR for all of my api request for the reasons you suggest. So much cool stuff in the rails community…

Leave a Reply

Your email address will not be published. Required fields are marked *