Wait_for_async_assigns - prevents "DBConnection.ConnectionError: client exited" errors in Phoenix LiveView tests

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:

4 Likes