Jerome
Jerome

Reputation: 6189

rails minitest stubbing to assert alternate method

A method replies upon two distinct APIs for geolocation, the second serving as a backup:

def admin_create
  @user_object =  User.create!(user_params)
  set_area(@user_object)
end

def set_area(resource)
  do_geocode_lookup(resource)
  if !resource.lon
    do_alternate_geocode_lookup(resource)
  end
end

Finding a data set that returns an empty lon/lat set is challenging (and orthodoxy pushes one to write the test first), so.. Is there a way to stub the test so that

sign_in operator_user
post admin_create_users_url, params: {user: { [...] } }
assert[...]

Upvotes: 0

Views: 82

Answers (1)

dbugger
dbugger

Reputation: 16389

Using Mocha you can stub out a method so that any instance of an object returns a specified value.

For example....

Account.any_instance.stubs(:reviews_enabled).returns(:true)

It also allows you test that a method was called...

Account.any_instance.expects(:review_started)

The fact you are altering the passed in resource instead of returning something makes things a bit trickier, but I'd be tempted to have do_geocode_lookup return true if it finds something, and false otherwise, to make things a little easier to test.

def set_area(resource)
  found = do_geocode_lookup(resource)
  unless found
    found = do_alternate_geocode_lookup(resource)
  end
  found
end

Then you could do something like this in your test...

  Geocoder.any_instance.stubs(:do_geocode_lookup).returns(:false)
  Geocoder.any_instance.expects(:do_alternate_geocode_lookup)
  result = sut.set_area(user)
  

If the expected method isn't called, you get an "expected method wasn't called" error. You can get far more sophisticated with the stubs and expects, but in this case you shouldn't have to.

Upvotes: 1

Related Questions