I’ve read Mocks and explicit contracts and I’m aware that mocking/stubbing is generally not “the elixir way”, but I’m still not sure what the “right” way is to test code that had dependancies that make external calls.
Here’s an example scenario:
- I’ve got a number applications that make calls to an external API to get an address from a latitude/longitude.
- An HTTP request to http://my.geoiplookup.com/address?lat=52&lng=13 returns an address string
- Rather than implementing this logic in each application, I create a library (a hex package) that wraps the HTTP calls to the external API, and include this library in my applications.
- The shared library ‘geo_service’, provides an interface that wraps the the external HTTP calls: e.g.
GeoService.address_lookup(%{lat: 52, lng: 13})
, which parses the response and returns a string
Let’s say I want to test one of my applications that use this ‘geo_service’ library - for example, one of my applications deals with users profiles, and I want to verify that the user’s address is set correctly.
How do I write tests my code that depends on the hex package, which makes external HTTP calls?
From what I’ve read, I believe I should use something like Bypass, to implement a dummy version of the external API calls, inject this into the library and write tests against these known responses.
However, by doing this, I feel I’m loosing decoupling between my application and library. Rather than simply depending on a library that takes in a lat/long and returns a string, my tests now need to know how the library get’s the address string, override the HTTP calls to return a custom response. I also need to implement this in all the applications that depend on this library.
In ruby I would have simply stubbed a call to GeoService.address_lookup
, or used the VCR library. I know there are elixir libraries that would allow me to do something similar, but I’d like to know the best practice for something like this in elixir.
Thanks in advance!