What are the best practices for avoiding side effect in ExUnit setup blocks?

The situation I am running into is while testing that a message isn’t pushed to a
channel when my authentication fails.

Since the setup block builds an authorized channel every time,
I already have the message I’m refuting even if my test doesn’t use the
provided socket.

Code Sample:

defmodule MyProject.FooChannelTest do
  use MyProject.ChannelCase

  alias MyProject.FooChannel

  setup do
    {:ok, _, socket} =
      socket("user_id", %{some: :assign})
      |> subscribe_and_join(FooChannel, "foo:lobby", %{"token" => "letmein"})

    {:ok, socket: socket}
  end

  test "doesn't list bars on unauthorized" do
    socket = socket()
    
    assert {:error, _} = subscribe_and_join(socket, FooChannel, "foo:lobby", %{"token" => "BAD TOKEN"})
    refute_push "bars", _
  end
end

One thought I have is to replace the setup block with a function like:

def authorized_socket() do
  {:ok, _, socket} =
    socket("user_id", %{some: :assign})
    |> subscribe_and_join(FooChannel, "foo:lobby", %{"token" => "letmein"})
  socket
end

so that the code simply isn’t executed unless requested. My concern is that the
setup block is mostly generated, so I want to be sure I’m not missing something
obvious that would prevent this issue.

1 Like