Testing Agents: to link or not to link?

I have a module that wraps an agent, and I started off by defining start_link/1 like so

defmodule Foo do
  @name :some_fooey

  def start_link(name \\ @name) do
    Agent.start_link(fn -> 0 end, name: name)
  end
end

defmodule FooTest do
  use ExUnit.Case, async: false

  setup do
    Foo.start_link(:some_name)
    :ok
  end

  test "some thing..." do
    assert 0 == Foo.run(:some_name)
  end
end

That’s all fine, I think. But then I thought about the use of a link versus manually cleaning up the process and landed on the idea of having both a start/1 and a start_link/1 defined so that I could use start/1 in my tests. It changed the code as follows:

defmodule Foo do
  @name :some_fooey

  def start_link(name \\ @name) do
    start_fn() |> Agent.start_link(name: name)
  end

  def start(name \\ @name) do
    start_fn() |> Agent.start(name: name)
  end

  defp start_fn do
    fn -> 0 end
  end
end

defmodule FooTest do
  use ExUnit.Case, async: false

  setup do
    {:ok, pid} = Foo.start(:some_name)

    on_exit fn ->
      Agent.stop(pid)
    end
    :ok
  end

  test "some thing..." do
    assert 0 == Foo.run(:some_name)
  end
end

My question is: is it worth it? It doesn’t feel worth it to me, and I haven’t read any material where start/1 is used, but I figured I’d ask.

Thanks!

1 Like

Is there a reason why the first solution doesn’t work for you? I prefer not to have functionality that is only needed for the tests, also in this case tests seem to work fine without the extra function?

Anyway in the end you will probably have your Foo started as part of the supervision tree which will make the second option trickier.

The only reason I’ve found is that at times linked processes can bring down ExUnit when they crash, which is a big red flag but doesn’t quite feel right either.

I’m happy with the first version, and since it is getting started in a supervision tree, it’s the right method.

I guess I’m wondering why no one has written anything on start/1 since it seems to be better suited to cleaning up after tests. It definitely does feel like ceremony though, since I won’t actually be using it in my code.