I’ve written an api client for some GitHub operations I need to perform and I just can’t seem to wrap my head around how to test this thing. I’ve read Mock and Explicit Contracts and I’ve looked at Stubr but I’m not putting the pieces together for my own needs.
I might not be understanding correctly, but it seems like if I use the technique discussed in José Valim’s blog post, I’ll end up writing three modules, two of which will only be for dev and testing. So I’ll clutter up my code base with stuff that isn’t actually used by my app. And if I write a module that always returns the same response for testing, then how would I test for cases where the api might return different results? Finally, if I do that wouldn’t it be fair to say that I’m not testing my api client that would be used in production, but rather I’m testing the mock?
Here is a stripped down sample. The module has a function called health
that will return true or false based on whether the auth token is returning a valid user.
defmodule GitHub.API do
use GenServer
def health(opts \\ []) do
GenServer.call(__MODULE__, {:health, opts})
end
def start_link do
GenServer.start_link(__MODULE__, Application.get_env(:siem_alerts, :github_token), name: __MODULE__)
end
def init(token) do
{:ok, token}
end
def handle_call({:health, opts}, _from, state) do
{:ok, response} = HTTPoison.get("https://api.github.com/user", [{"Authorization", "token #{state}"}])
{:ok, body} = Poison.decode(response.body)
health_status = case body do
%{"type" => "User"} -> true
_ -> false
end
case Keyword.get(opts, :details, false) do
true -> {:reply, body, state}
false -> {:reply, health_status, state}
end
end
end
Assume that the above is working properly. My phoenix controller just returns a json status when you GET /health
that consists of running the health
function above. How could I make these two tests pass?
defmodule MyApp.HealthControllerTest do
use MyApp.ConnCase
describe "getting health status" do
test "GET /health indicates if GitHub key is valid" do
response = build_conn
|> get(health_path(build_conn, :index))
|> json_response(200)
assert response == %{"healthy" => true, "valid_github_key" => true}
end
test "GET /health indicates if GitHub key is not valid" do
response = build_conn
|> get(health_path(build_conn, :index))
|> json_response(200)
assert response == %{"healthy" => false, "valid_github_key" => false}
end
end
end