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

zookzook
If you want to use the MongoDB in your next Killer-App-Project, but you did not dare ask because otherwise many would advise you to use P...
New
slouchpie
Warmest greetings, comrades. I recently started using :dns_cluster (GitHub - phoenixframework/dns_cluster: Simple DNS clustering for dis...
New
anuragg
Hi everyone! I’m the founder of Render, a new cloud provider with native support for Elixir. When we launched Elixir support the most po...
New
sergio
Hey there, we’re going to walk through deploying a Phoenix app to a DigitalOcean droplet, manually - no tools no nothing. Just straight u...
New
rhcarvalho
After collecting information from multiple sources (this forum, blogs, StackOverflow and GitHub), I was finally able to successfully embe...
New
Zurga
In a quest to optimize the amount of data sent between the server and client I recently decided to try to use MessagePack instead of JSON...
New
water
I’ll post this here, It might help someone in the future. Feedback is greatly appreciated. I use it with direnv on NixOS, It should wor...
New
niku
I write an article Parameterized testing with ExUnit.The key concept is using ExUnit.Case.register_test/4 such as ExUnit.start() defmod...
New
anuragg
We finally have a Mix clustering guide to go with Phoenix deployment with Mix Releases. Deploy an Elixir Cluster with Mix Releases and l...
New
voltone
The EEF’s Security WG has released the first public draft of the Secure Coding and Deployment Hardening Guidelines for BEAM languages. “...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
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
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
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
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

We're in Beta

About us Mission Statement