ExUnit: replace an OTP process/service for a single test

I’ve got this worker setup in my main application start:

cache_config = Application.get_env(:my_app, MyApp.Cache)
children = [
  worker(Redix, [[host: cache_config[:hostname], port: cache_config[:port]], [name: :redix]])
]

opts = [strategy: :one_for_one, name: CoachActivity.Supervisor]
Supervisor.start_link(children, opts)

I can then do:

Redix.command(:redix, ...)

I have a single test for which I need that OTP process configured to hit a different port. At first I thought I’d just change the configuration with Application.put_env/3 but that didn’t do the trick. The Redix client has already initialized the port by then and changing it doesn’t ripple down as I’d hoped.

So my next thought (and here is where my ignorance reveals itself) is that I could somehow replace the :redix worker at the start of the test. But I have no idea how to proceed.

Is there a testing idiom for this sort of thing?

Provided you do not run the test asynchronously with others (no async: false), as this would mess up concurrent tests, you can do the following:

  1. In setup block set new configuration and restart the application:

    Application.stop(:my_app)
    Application.put_env(:my_app, MyApp.Cache, [port: 1234])
    Application.start(:my_app)

  2. In on_exit callback reverse what you did so the rest of tests use default config.

It’s not tested but I am certain it will work.

Perfect! It was the concept of stopping, reconfiguring and restarting the application that I was completely missing. More specifically the stop/start aspect.

I appreciate the help :slight_smile: