How To Test That a Resource Published an Event? assert_receive says mailbox is "empty"

How do I test that my Category resource is sending notifications?

Here my resource definition

defmodule MyApp.KnowledgeBase.Category do
  use Ash.Resource,
    domain: Helpcenter.KnowledgeBase,
    data_layer: AshPostgres.DataLayer,
    # Tell Ash to broadcast/ Emit events via pubsub
    notifiers: Ash.Notifier.PubSub
    
  pub_sub do
    module HelpcenterWeb.Endpoint

    prefix "categories"

    publish_all :update, [[:id, nil]]
    publish_all :create, [[:id, nil]]
    publish_all :destroy, [[:id, nil]]
  end
end

Here is the test:

test "'categories'  event should be published on create" do
      Helpcenter.KnowledgeBase.Category
      |> Ash.Changeset.for_create(:create, %{
        name: "Art 1",
        slug: "art-1",
        description: "descrpt-1"
      })
      |> Ash.create()

      assert_receive {:broadcast, "categories", "create", %Ash.Notifier.Notification{}}
    end

The above tests returns:

     Assertion failed, no matching message after 100ms
     The process mailbox is empty.

You have to subscribe before you can successfully assert broadcast.

2 Likes

Thanks @zachdaniel,

subscribing to the event before creating categegory worked

Here is the working test function

    test "'categories' pubsub event is published on create" do
      # Subscribe to the event so we can test whether it is being fired
      HelpcenterWeb.Endpoint.subscribe("categories")

      attributes = %{name: "Art 1", slug: "art-1", description: "descrpt-1"}

      Helpcenter.KnowledgeBase.Category
      |> Ash.Changeset.for_create(:create, attributes)
      |> Ash.create()

      # Confirm that the event is being recieved and its data
      assert_receive %Phoenix.Socket.Broadcast{topic: "categories", payload: category}
      assert category.data.name == attributes.name
      assert category.data.slug == attributes.slug
      assert category.data.description == attributes.description
    end
1 Like