Asd

Asd

How-to: Async tests with application env.

How to test with application env in async: true

It is quite common for Elixir application to be configured via application env (which is set in config/ files and accessed with Application.get_env and such). However, this application env is global and therefore is very difficult to get right when testing with use ExUnit.Case, async: true.

This article describes how to overcome this problem with Repatch library

Problem

You have a configuration which controls a feature-flag in config/config.exs

import Config
config :my_app, :features,
  lucky_feature_enabled: System.get_env("LUCKY_FEATURE") == "1"

Which controls this simple code

defmodule EightBall do
  def ask(_question) do
    if Application.get_env(:my_app, :features)[:lucky_feature_enabled] do
      Enum.random([:absolutely, :sure, :definitely])
    else
      Enum.random([:no, :no_way, :definitely_not])
    end
  end
end

And you have these tests

test "Enabled feature" do
  Application.put_env(:my_app, :features, lucky_feature_enabled: true)
  assert EightBall.ask("Is it awesome?") in [:absolutely, :sure, :definitely]
end

And

test "Disabled feature" do
  assert EightBall.ask("Is it awesome?") in [:no, :no_way, :definitely_not]
end

Testing with async: true won’t be possible, because if the test of enabled feature test is executed before the disabled test, env will be set and the second test will fail. And executing tests with async: false reduces performance of testing and requires manual cleanup of application env after the test completion.

Solution

Repatch library provides a simple solution to the problem.

  1. First, install it with this code in mix.exs file:

    def deps do
      [
        {:repatch, "~> 1.2"}
      ]
    end
    

    Then mix deps.get

  2. Setup Repatch with this code in test/test_helper.exs file:

    ExUnit.start()
    Repatch.setup()
    Repatch.Application.setup()
    
  3. And just add this into your test file and env will be isolated for each test.

    use Repatch.ExUnit, isolate_env: :local
    

Voila

Now these tests are safe to be used with async: true testing mode. Repatch is a powerful and small library which makes testing in Elixir very simple. Please check out the docs for all available features:

Most Liked

com

com

This saved my bacon, testing some app config logic wasn’t going well. Thank you!

Where Next?

Popular in Guides/Tuts Top

hlx
Typed my very first blog post ever, hope it will help some people https://henricus.xyz/roll-your-own-email-password-authentication-with...
New
tomciopp
TLS 1.3 has been out for a little over a year now, but it has been unavailable in Phoenix due to erlang’s handling of ssl. With the most ...
New
zachallaun
Hey friends, wanted to share a tiny shell script I’ve been using to start Livebook with easy access to either a running production server...
New
eclark
I’ve been working on a phoenix project lately and I wanted to use the latest versions of everything. Webpack 5 had some breaking changes ...
New
jtormey
Hello! Having written a lot of LiveView code, I’ve made some VS Code snippets to speed up writing callbacks for LiveViews and LiveCompon...
New
OvermindDL1
Ran across this recently, it's a set of cheatsheet inforgraphic things of the OTP behaviours on the BEAM:
New
nelsonic
When we were figuring out how to use Phoenix LiveView we got stuck a few times. So in order to save other people time, we created a comp...
New
dmitriid
This is not a question, but a post for anyone who may need it in the future. Sometimes some browsers may mangle the filename if it’s non-...
New
jswny
Hello everyone, I recently redesigned my entire deployment process for Phoenix apps based on Docker. I really like the strategy that I ca...
New
AstonJ
..or as and when you can think of one :icon_cool: This thread my also be of interest: What took you way too long to figure out? :003:
New

Other popular topics Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement