Extract common ExUnit setup

Among many of the tests in our codebase there is a setup repeated multiple times, which is basically starting some required processes (mainly Registries) and looks something like this:

setup do
  start_supervised(MyApp.MyModule.Supervisor)
  start_supervised({Registry, keys: :unique, name: MyApp.Registry.ById})
  ...
  :ok
end

I want to extract this in a common module so it can be used easier.

My idea was something like this:

  1. Create a module with setup functions under test/support
  2. Import the module on the required test
  3. Call them with in the test setup like setup :set_my_registries (like defined here

The problem is that the start_supervised function is of course not defined in my module.

My questions are:

  • Can I import/require something from ExUnit to make it work?
  • Should I try to hack it using Macros and use it in the test?
  • Is there a better approach?

PS: I know the philosophy in Elixir tests is to be descriptive but is very annoying when something change names or now there is another dependency and added in all the setup blocks

That should work.

Let me know if you figure out a good solution to this, I’m encountering the same exact problem right now where I need to start a bunch of things for each test in the setup block.

Can you just define a special case template like conn_case, data_case, etc. that is YourApp.RegistryCase and put that common code in the setup or using block? That way the tests that need it just use YourApp.RegistryCase and those that don’t use the usual ones.

2 Likes

So for anyone having a similar issue you can import ExUnit.Callbacks and it should do the trick.
My support module (test/support/my_app_mock.ex) now looks something like this

defmodule MyApp.Mock do
  import ExUnit.Callbacks

  def set_scaffold(_context) do
    start_supervised(MyApp.MyModule.Supervisor)
    start_supervised({Registry, keys: :unique, name: MyApp.Registry.ById})
    ...
    :ok
  end
end

And then it can be used like

...
import MyApp.Mock

setup :set_scaffold

Just don’t forget to add the path to the compilation path list (example here)

2 Likes