I’ve been running into DBConnection.ConnectionError: client exited errors in LiveView tests whenever using assign_async/3. The async tasks keep running after the test completes and crash when trying to access the closed database connection.
There’s been an open issue about this for a while, so I extracted a helper function we’ve been using:
test "loads data asynchronously", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/products")
html = render_async(view)
assert html =~ "Products"
wait_for_async_assigns(view)
end
It waits for all async operations to complete before the test exits. The timeout defaults to ExUnit’s assert_receive_timeout but can be configured.
Installation
def deps do
[
{:wait_for_async_assigns, "~> 0.1.0", only: :test}
]
end
Import in your test case module:
defmodule MyAppWeb.ConnCase do
use ExUnit.CaseTemplate
using do
quote do
import Phoenix.ConnTest
import Phoenix.LiveViewTest
import WaitForAsyncAssigns
@endpoint MyAppWeb.Endpoint
end
end
end
The package also includes a Credo check that warns when LiveView tests are missing wait_for_async_assigns/1:
# .credo.exs
%{
configs: [
%{
name: "default",
requires: ["deps/wait_for_async_assigns/lib/credo/check/wait_for_async_assigns.ex"],
checks: %{
enabled: [
{Credo.Check.WaitForAsyncAssigns, []}
]
}
}
]
}
Links: Hex
GitHub:




















