Skip to content

Instantly share code, notes, and snippets.

@coryodaniel
Created June 27, 2019 23:54
Show Gist options
  • Save coryodaniel/0b3b476b0ef20dab15e685e216acf5da to your computer and use it in GitHub Desktop.
Save coryodaniel/0b3b476b0ef20dab15e685e216acf5da to your computer and use it in GitHub Desktop.
Per process / test mock
defmodule K8s.Mock do
@moduledoc """
A single interface to use for an environment, but allow each process to define its own module that implements behaviors to respond.
Good for tests, two tests can independently register the HTTP responses they should receive w/o having the confusing shared http_provider mock currently in k8s
"""
use GenServer
# TODO methods that the http behavior has go here, when executing should look up
# the registered module for the calling pid
def test() do
mod = lookup(self())
mod.test()
end
@doc """
Starts the mock.
"""
def start_link(opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
@doc """
Lookup the handler for this test
"""
def lookup(test_pid) do
GenServer.call(__MODULE__, {:lookup, test_pid})
end
def list(), do: GenServer.call(__MODULE__, :list)
@doc """
Register the handler for this test
"""
def register(test_pid, module) do
GenServer.call(__MODULE__, {:register, test_pid, module})
end
@impl true
def init(:ok) do
{:ok, %{}}
end
def handle_call(:list, _from, state) do
{:reply, state, state}
end
@impl true
def handle_call({:lookup, test_pid}, _from, pids) do
{:reply, Map.get(pids, test_pid), pids}
end
@impl true
def handle_call({:register, test_pid, module}, _from, state) do
new_state = Map.put(state, test_pid, module)
{:reply, new_state, new_state}
end
end
defmodule Foo do
def test(), do: "foo"
end
defmodule Bar do
def test(), do: "bar"
end
K8s.Mock.start_link([])
K8s.Mock.register(self(), Foo)
IO.puts K8s.Mock.test()
spawn(fn ->
K8s.Mock.register(self(), Bar)
IO.puts K8s.Mock.test()
end)
IO.puts K8s.Mock.test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment