How to mock all http calls to several services in test

Hello everyone,

I’m working on an app making calls to externals services. I’m using existing libs to make those external calls.

In the worst case scenario, one call to the external service equals to 4 calls

  1. First call → expired token
  2. Refresh token call → token refreshed
  3. Redo first call → too much call, retry later
  4. Redo first call → {:ok, response}

How can I test the behavior of my app when my app use libs making calls to external services ?

Is ByPass the way to go ? Should I use ExVCR ?

Thanks for any help

You can parametrize the code which uses the external libraries by abstracting the libraries APIs using behaviors and making the code depend on modules implementing said behaviors. Then use mox to mock a behvior. If your code depends on Finch, create an HTTP client behavior, mock it with mox and pass it as a dependency to the module which makes the calls. This is one way to test functionality which does side effects.

I would create a module that wraps my interactions with the api. For example, if I were talking with Twitter, I would write a MyApp.TwitterClient module. I would implement it with a Behavior as Mox requires, then in tests replace it with a mock.

In our setup we’re dealing with OAuth a lot, so we need to make sure that we get every details right. The problem with Bypass is that you’re forced to change the URL. We went a similar route to ExVCR, but we’re using Tesla. Here’s our setup:

  • In :dev, we use our hand-written adapter that records all %Tesla.Env{}s and dumps them to files as request+response pairs,
  • In :test we feed the recordings to a mock adapter built using Mox.

Thanks for all your answers.

I hoped it could be possible to trick the HTTP calls and return the answers in test according to the request without mocking the lib I’m using.