GenServer failing in tests due to already torn down db connection

I am writing an ex_unit test for a context function create_requirement/1. The challenge I’m facing is that create_requirements/1 sends a message to a GenServer to do some side effects after create, and I am facing a race condition, where the test process exits, and tears down the database connection, before the GenServer tries to write to the DB, causing an error:

12:59:16.866 [error] GenServer MyApp.MatchMaintainer terminating
** (stop) exited in: DBConnection.Holder.checkout(#PID<0.1378.0>, [log: #Function<13.92833450/1 in Ecto.Adapters.SQL.with_log/3>, source: "opportunities", cast_params: [], pool: DBConnection.Ownership, repo: MyApp.Repo, timeout: 15000, pool_size: 28])
    ** (EXIT) shutdown: "owner #PID<0.1377.0> exited"

Is there a best practice for how to avoid this?
Is my error not setting up the test environment correctly, or is having a GenServer handles a side effect from within create_requirement/1 poor practice?

I suspect this is a common concern, and I’m just not using the right approach (as I don’t know what the right approach is)

You likely need to have a conditional code – only executed in the test Mix.env – that sends message to a process on certain events. That should force your test case to wait.

One way I’ve used is to send any synchronous message to the GenServer process - even just :sys.get_state is enough.

That’ll ensure that the process has finished handling earlier messages and avoid the race entirely.

4 Likes