Reputation: 93
I'm currently working on my first big elixir project and wanted to properly utilize testing this time.
However, if I add my Modules to the "normal" supervisor, i cannot start them again with start_supervised!
and all tests fail with Reason: already started: #PID<0.144.0>
Here is my code:
(application.ex)
defmodule Websocks.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
def start(_type, _args) do
children = [
{Websocks.PoolSupervisor, []},
{Websocks.PoolHandler, %{}}
# {Websocks.Worker, arg}
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Websocks.Supervisor]
Supervisor.start_link(children, opts)
end
end
Some of my tests:
defmodule PoolHandlerTest do
use ExUnit.Case, async: true
alias Websocks.PoolHandler
doctest PoolHandler
setup do
start_supervised!({PoolHandler, %{}})
%{}
end
test "adding two pools and checking if they are there" do
assert PoolHandler.add(:first) == :ok
assert PoolHandler.add(:second) == :ok
assert PoolHandler.get_pools() == {:ok,%{:first => nil, :second => nil}}
end
and the pool handler:
defmodule Websocks.PoolHandler do
use GenServer
# Client
def start_link(default) when is_map(default) do
GenServer.start_link(__MODULE__, default, name: __MODULE__)
end
# Server (callbacks)
@impl true
def init(arg) do
{:ok, arg}
end
end
(I cut out the stuff i think is not necessary, but the complete code is on github here: github)
Thanks in advance for any help i get!
Upvotes: 1
Views: 1143
Reputation: 23194
As @Everett mentioned in the comment - your application will already be started for you when you mix test
, so there is no need to start your GenServers
again. It seems like you're interacting with the global instance in your test, so if that's what you want, then it should just work.
However, if you'd like to start a separate instance just for your test, you need to start an unnamed one. For example, you could add an optional pid argument to your wrapper functions:
defmodule Websocks.PoolHandler do
# ...
def add(server \\ __MODULE__, value) do
GenServer.call(server, {:add, value})
end
# ...
end
Then, instead of using using start_supervised!
like you do, you can start an unnamed instance in your setup
and use it in your tests like so:
setup do
{:ok, pid} = GenServer.start_link(PoolHandler, %{})
{:ok, %{handler: pid}}
end
test "adding two pools and checking if they are there", %{handler: handler} do
PoolHandler.add(handler, :first)
# ...
end
Upvotes: 4