Skip to content

Instantly share code, notes, and snippets.

@aleDsz
Last active December 8, 2020 20:26
Show Gist options
  • Save aleDsz/7a02a9d2bc22972691203bb6ee0a0312 to your computer and use it in GitHub Desktop.
Save aleDsz/7a02a9d2bc22972691203bb6ee0a0312 to your computer and use it in GitHub Desktop.
Elixir test with Mox
# prod.exs
use Mix.Config
config :my_app, twitter_client: MyApp.Twitter.HTTP
# test.exs
use Mix.Config
config :my_app, twitter_client: MyApp.TwitterMock
# mix.exs
defmodule MyApp do
def deps do
[
{:mox, "~> 1.0", only: :test}
]
end
end
defmodule MyApp.Twitter.Client do
@callback get_tweets_from_user(username :: String.t()) :: {:ok, list(map())} | {:error, map() | atom()}
end
defmodule MyApp.Twitter do
def get_tweets_from_user(username) do
client().get_tweets_from_user(username)
end
defp client do
Application.get_env(:my_app, :twitter_client)
end
end
# Production
defmodule MyApp.Twitter.HTTP do
@behaviour MyApp.Twitter.Client
@impl true
def get_tweets_from_user(username) do
# your implementation ...
end
end
# Tests
# test/support/mocks.ex
Mox.defmock(
MyApp.TwitterMock,
for: MyApp.Twitter.Client
)
# test/my_app/twitter_test.exs
defmodule MyApp.TwitterTest do
use ExUnit.Case
# Import Mox to allow validation if some behaviour function is called
import Mox
setup :verify_on_exit!
describe "get_tweets_from_user/1" do
test "returns list of tweets from user" do
username = "aleDsz"
# Here, we expect that mock `MyApp.TwitterMock` will be called on function `get_tweets_from_user` only
# `1` time and with arity `1` (fn username -> end)
#
# And now, we can define how this mock will return value and define how our app should handle this type
# of response.
Mox.expect(MyApp.TwitterMock, :get_tweets_from_user, 1, fn ^username ->
result = [
%{
"username" => username,
"message" => "foo bar"
}
]
{:ok, result}
end)
assert {:ok, [%{"username" => ^username}]} = MyApp.Twitter.get_tweets_from_user(username)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment