Per-test configuration isolation for ExUnit.

Provides put_config/3, get_config/2, and diff/1 to manage test-scoped application config that intercepts Application.get_env transparently.

Setup

In test/test_helper.exs:

Mace.Store.init()
ExUnit.start()

Modules that need Application.get_env interception must also call Mace.Mock.install() in a setup_all block.

In your test module:

defmodule MyTest do
  use ExUnit.Case, async: true

  setup do
    Mace.put_config(:my_app, :timeout, 100)
    :ok
  end

  test "uses overridden timeout" do
    # Application.get_env(:my_app, :timeout) => 100
    assert MyModule.do_thing() == :ok
  end
end

Summary

Functions

Records the current process's config diffs and then resets. Optional — replace a bare Mace.reset/0 in on_exit to enable automatic config-diff display on test failure.

Same as get/2 but logs the full tree walk path to stderr. Use to diagnose why a test isn't seeing expected config.

Removes a specific config override for the current process.

Returns a formatted diff string comparing the current process's config overrides against the application defaults.

get(app, key) deprecated

Gets the active config override for the current process. Returns {:ok, value} or :error.

Returns the current pid's full config overrides as a nested map. Useful for debugging and for manual config transfer to spawned processes.

Sets multiple config overrides from a keyword list.

Sets a config override for the current test process.

Clears all config overrides for the current test process. Normally unnecessary — cleanup happens automatically when the test process exits via the DOWN handler. Use as an escape hatch when you need to explicitly clear config mid-test.

set(app, kvlist) deprecated

Spawns a Task that inherits the current process's config overrides. Use instead of Task.async/1 when the spawned code calls Application.get_env.

Functions

cleanup(context)

Records the current process's config diffs and then resets. Optional — replace a bare Mace.reset/0 in on_exit to enable automatic config-diff display on test failure.

Example

setup context do
  Mace.put_config(:my_app, :timeout, 100)
  on_exit(fn -> Mace.cleanup(context) end)
  :ok
end

debug_get(app, key)

Same as get/2 but logs the full tree walk path to stderr. Use to diagnose why a test isn't seeing expected config.

delete(app, key)

Removes a specific config override for the current process.

Sets the key to nil, mirroring Application.delete_env/2. Subsequent Mace.get_config/2 calls return {:ok, nil}.

Examples

iex> Mace.put_config(:my_app, :timeout, 100)
iex> Mace.delete(:my_app, :timeout)
:ok
iex> Mace.get_config(:my_app, :timeout)
{:ok, nil}

diff(app)

Returns a formatted diff string comparing the current process's config overrides against the application defaults.

Returns empty string if no overrides or all overrides match defaults.

get(app, key)

This function is deprecated. Use Mace.get_config/2 instead.

get_config(app, key)

Gets the active config override for the current process. Returns {:ok, value} or :error.

pid_config()

Returns the current pid's full config overrides as a nested map. Useful for debugging and for manual config transfer to spawned processes.

Example

config = Mace.pid_config()
# => %{my_app: %{timeout: 100, debug: true}}

put_config(app, kvlist)

Sets multiple config overrides from a keyword list.

Example

Mace.put_config(:my_app, timeout: 100, debug: true)

put_config(app, key, value)

Sets a config override for the current test process.

Subsequent calls to Application.get_env(app, key) from the same process will return value instead of the real application config.

reset()

Clears all config overrides for the current test process. Normally unnecessary — cleanup happens automatically when the test process exits via the DOWN handler. Use as an escape hatch when you need to explicitly clear config mid-test.

set(app, kvlist)

This function is deprecated. Use Mace.put_config/2 instead.

set(app, key, value)

This function is deprecated. Use Mace.put_config/3 instead.

task(fun)

Spawns a Task that inherits the current process's config overrides. Use instead of Task.async/1 when the spawned code calls Application.get_env.

Example

task = Mace.task(fn -> MyModule.do_async_work() end)
result = Task.await(task)