Search⌘ K
AI Features

Testing the Actual Interaction with Services

Explore strategies for testing actual interactions with external services in Elixir applications. Understand how to verify real API requests, handle dependencies, and mitigate common issues like rate limiting and test brittleness to ensure robust integration and end-to-end tests.

When working with third-party APIs like the weather API, we push the code that integrates with the API outside our application in a lightweight wrapper. When we’re testing our application, we’re able to swap out that small part with a double to run the rest of our application. However, we also need to make sure that the code that interacts with the API works. We’ll need a test for that.

In our weather API application, the code that interacts with the weather API is this:

Elixir
defmodule SoggyWaffle.WeatherAPI do
@behaviour SoggyWaffle.WeatherAPI.Behaviour
@spec get_forecast(String.t()) ::
{:ok, map()} | {:error, reason :: term()}
def get_forecast(city) when is_binary(city) do
app_id = SoggyWaffle.api_key()
query_params = URI.encode_query(%{"q" => city, "APPID" => app_id})
url =
"https://api.openweathermap.org/data/2.5/forecast?" <> query_params
case HTTPoison.get(url) do
{:ok, %HTTPoison.Response{status_code: 200} = response} ->
{:ok, Jason.decode!(response.body)}
{:ok, %HTTPoison.Response{status_code: status_code}} ->
{:error, {:status, status_code}}
{:error, reason} ->
{:error, reason}
end
end
end

We’re using HTTPoison as our HTTP client. The get/1 function lets us send a GET HTTP request to the URL we pass to it and returns an [:ok, ...