Hi,
I’m testing a PhoenixController which triggers background jobs and I don’t know how to test the background job doesn’t fail.
So, I have a Controller
which sends a message to a GenServer
. The Genserver
does something and then, triggers a cast
. I just want to make sure the cast
finishes properly but I don’t know how to do it.
Here a sample code, reproducing what I’m talking about:
defmodule MyApplication do
use Application
def start(_type, _args) do
import Supervisor.Spec
opts = [strategy: :one_for_one, name: MyApplication.Supervisor]
Supervisor.start_link([worker(MyGenServer, [])], opts)
end
end
defmodule MyGenServer do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, [], [name: __MODULE__])
end
def do_something(thing) do
GenServer.call(__MODULE__, {:do_something, thing})
end
def do_something_else(thing) do
GenServer.cast(__MODULE__, {:do_something_else, thing})
end
def handle_call({:do_something, thing}, _from, state) do
# do all the synchronous stuff
# ....
# then trigger some slow work behind the scene
do_something_else(thing)
{:reply, :ok, state}
end
def handle_cast({:do_something_else, thing}, state) do
Process.sleep(100)
raise "Booom from #{thing}"
{:noreply, state}
end
end
defmodule MyController do
def create(params) do
MyGenServer.do_something(params["form"]["name"])
end
end
defmodule DummyTest do
use ExUnit.Case, async: true
setup_all do
MyApplication.start(nil, nil)
:ok
end
test "how can I wait for the handle_cast to finish?" do
assert :ok == MyController.create(%{"form" => %{"name" => "dummy"}})
end
test "another test just to make sure mix doesn't stop before the end of the cast function" do
Process.sleep(1_000)
assert true
end
end
The output is
mix test
warning: this check/guard will always yield the same result
test/dummy_test.exs:70
13:54:15.665 [error] GenServer MyGenServer terminating
** (RuntimeError) Booom from dummy
test/dummy_test.exs:39: MyGenServer.handle_cast/2
(stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:667: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:do_something_else, "dummy"}}
State: []
..
Finished in 4.0 seconds
2 tests, 0 failures
Randomized with seed 468679
I would like to have 2 tests, 1 failure
instead of 2 tests, 0 failure
but I don’t know how to do it.
Thanks for your help