Trying to learn basic code testing with elixir and have trouble wrapping my head around testing async functions(genserver's handle_info and cast).
One way that works but feels wrong is using :timer.sleep(x)
after casting async functions.
For example, imagine handle_cast
that is processing list of items from state and dispatching calls to another module that will fetch data from external API and when done it will send message(api data) back to that same genserver.
What would be the best way to test this? Can I monitor genserver messages/mailbox inside the test?
edit: Another example, say in init I do this to get initial state from db:
Process.send_after(self(), :started, 0)
And :started looks like:
defhandleinfo :started, state: state, do: new_state(UserServerStarted.get_data(state))
Do I have any other option then :timer.sleep to check if UserServerStarted returned correct thing? I know I could just test that module/unit separately but I want to do full integration test.
Here is how I am doing it now:
... SETUP - Supervisor start UserServer...
test "spin up server and inital tree after user registers", %
{user: user} do
:timer.sleep(500)
assert %{"default" => [nil]} == GenServer.call(UserServer.via_tuple(user.id), :get)
end
Process.info(pid, :messages)
but that would not reliably work with GenServer as the GenServer would process the message as soon as it receives it unless it's busy handling a previous message. – Dogbert