Packages

A tool for managing application env state within tests.

Current section

Files

Jump to
temporary_env lib temporary_env.ex
Raw

lib/temporary_env.ex

defmodule TemporaryEnv do
@moduledoc """
Temporarily set Application environment variables.
Quite handy for testing, but remember to set `async: false` for tests suites
it is used in.
"""
@default :temporary_env_default_value_for_unset_var
@doc false
defmacro __using__(_) do
quote do
require TemporaryEnv
test "TemporaryEnv test case async status", context do
refute context.async, """
TemporaryEnv cannot be used in async tests.
To make this test case synchronous, modify your use of
ExUnit.Case like so:
use ExUnit.Case, async: false
"""
end
end
end
@spec set(atom, [{atom, any}], [{:do, any}]) :: any
@doc """
Temporarily set an Application environment value within a block.
TemporaryEnv.set :my_app, greeting: "Hello!" do
# :greeting for :my_app is now "Hello"
end
# :greeting for :my_app is back to its original value
This *does* modify global state, so do not use it in an async situation.
"""
defmacro set(app, [{key, value}], do: block) do
quote do
# Get original state
temporary_env_original_value = Application.get_env(
unquote(app), unquote(key), unquote(@default)
)
try do
# Set temporary state
Application.put_env unquote(app), unquote(key), unquote(value)
unquote(block)
after
# Restore original state
case temporary_env_original_value do
# when the value was previously unset
unquote(@default) ->
Application.delete_env( unquote(app), unquote(key) )
# when the value was previously set
_ ->
Application.put_env(
unquote(app), unquote(key), temporary_env_original_value
)
end
end
end
end
end