Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally start GenServer in tests

I have implemented a GenServer that listens to an external message queue via long polling. For that, I am starting the GenServer with the start of the application, i.e. within the start/2 function of my application.ex file I specified an extra child in the supervisor list:

children = [
    supervisor(MyApp.Repo []),
    supervisor(MyAppWeb.Endpoint, []),
    supervisor(MyApp.MessageQueueGenServer, [])
]

This list is then started with:

Supervisor.start_link(children, [strategy: :one_for_one, name: MyApp.Supervisor])

Now I have the problem that the GenServer is of course also started when I am running some (1) database setup with mix ecto.reset or (2) tests with mix test.

For the tests (2) I could, e.g. only add MyApp.MessageQueueGenServer to the children list if Mix.env != :test.

But what about (1)? How to avoid starting my GenServer when running mix ecto.reset/mix ecto.setup/etc.?

like image 704
Tom Avatar asked Oct 28 '25 01:10

Tom


1 Answers

I had the same issue and I have it resolved with a configuration parameter.

config/config.exs

config :myapp, :children, [
  MyApp.Repo, MyAppWeb.Endpoint, MyApp.MessageQueueGenServer]

config/dev.exs

# config :myapp, :childen [] # tune it for dev here

config/test.exs

config :myapp, :children, [
  MyApp.Repo, MyAppWeb.Endpoint]

your server file

children = [
  :myapp
  |> Application.get_env(:children)
  |> Enum.map(&supervisor(&1, [])
]

Sidenote: you might want to consider using modern style of children declaration, since Supervisor.Spec is deprecated, that way it would be even cleaner:

children = Application.get_env(:myapp, :children)
like image 135
Aleksei Matiushkin Avatar answered Oct 30 '25 15:10

Aleksei Matiushkin