Mocking HTTP Responses in Elixir and Phoenix
I just came across this error while attempting to mock the response of a 3rd party api:
** (UndefinedFunctionError) function LeagueInfoMocks.get_live/0 is undefined (module LeagueInfoMocks is not available)
The Problem
I couldn't wrap my head around it. I have this simple mock module defined:
defmodule LeagueInfoMocks do
def get_live do
%{...}
end
end
And a test module to interact with the get_live function:
defmodule LeagueInfoTest do
use ExUnit.Case
test "format_info" do
data = LeagueInfoMocks.get_live()
[match | _tail] = data
assert LeagueInfo.format_info(data) == %{...}
end
end
But running mix test
would consistently give me the ** (UndefinedFunctionError) function LeagueInfoMocks.get_live/0 is undefined (module LeagueInfoMocks is not available)
.
The Solution
Most articles and threads mentioned moving the LeagueInfoMocks
module in the test/support/*
directory, so I did. This didn't change the error message.
I eventually found this Stackoverflow comment that mentioned some configuration needed in the mix.exs
file.
Supposedly, mix phx.new
adds the test/support/*
support when a Phoenix project is created. In my case, I'm building off of a simple Elixir application. This required me to configure my mix.exs
file to look like so:
defmodule LolesportsConsumer.MixProject do
use Mix.Project
def project do
[
app: :lolesports_consumer,
version: "0.1.0",
elixir: "~> 1.15",
start_permanent: Mix.env() == :prod,
deps: deps(),
elixirc_paths: elixirc_paths(Mix.env())
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:httpoison, "~> 2.1"},
{:jason, "~> 1.4"}
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
end
The key differences were:
- Adding
elixirc_paths: elixirc_paths(Mix.env())
toproject
- Adding these two lines to the file:
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
Conclusion
With these configuration changes, I am able to properly call LeagueInfoMocks.get_live()
and write tests against an expected HTTP response.