DEV Community

Cover image for How to dynamically load configurations for tests at runtime within Elixir libraries
Alexandre Antonio Juca
Alexandre Antonio Juca

Posted on

4 1

How to dynamically load configurations for tests at runtime within Elixir libraries

I recently started working with elixir and had the opportunity to create a library at Next Business Solutions called ExOktaAuth that enables elixir applications to handle signup/sign-in flows using Okta's OAuth 2.0/OIDC service.

Now while writing tests for the library, I faced an issue while trying to test a function that was dependent on application configuration that is usually defined in the config.ex file of the phoenix application that is using the library as a dependency.

This is a snippet of the functions code:

config = :ex_okta_auth
             |> Application.fetch_env!(__MODULE__)
             |> validate_config!(:client_id)
             |> validate_config!(:client_secret)
             |> validate_config!(:site)
             |> validate_config!(:redirect_uri)


    site = Keyword.get(config, :site)
    ExOAuth2.Client.new([
      strategy: __MODULE__,
      client_id: Keyword.get(config, :client_id),
      client_secret: Keyword.get(config, :client_secret),
      site: site,
      redirect_uri: Keyword.get(config, :redirect_uri),
      authorize_url: site <> "/v1/authorize",
      token_url: site <> "/v1/token"
    ])
    |> ExOAuth2.Client.put_serializer("application/json", Jason)

Essentially what this code does is load and validate configuration options that it acquires from the application's config.ex file and uses that to create an %ExOAuth2.Client struct that is responsible for setting up the definitions used for interactions with okta's API.

This works all good and well but implementing a unit test for this function turned out to be quite difficult for me since I am new to elixir.

Since the function was dependent on the configuration, I had to find a way to load a specific configuration at runtime so the function could acquire those configuration options during testing.

I came up with the following solution.

Step 1: Define configuration to load during test

Create a file named config.ex in the test/ folder of your library.

import Config

config :ex_okta_auth, ExOktaAuth.Okta,
    client_id: "isoaspoaisa",
    client_secret: "kajskaljs",
    site: "http://127.0.0.1:4000/default",
    redirect_uri: "https://your-apps-callback-uri"

Step 2: Load config dynamically during tests

Config.Reader.read!("test/config.ex")
|> Application.put_all_env()

Here you can see how I used this solution in the context of a real test.

defmodule ExOktaAuthTest do
  use ExUnit.Case
  doctest ExOktaAuth

  setup_all do
    setup_config()
    {:ok, state: :ok}
  end

  def setup_config() do
    Config.Reader.read!("test/config.ex")
    |> Application.put_all_env()
  end

  test "Should return a valid client" do
    assert ExOktaAuth.Okta.client == Helpers.valid_client
  end
end

I would love to know if there is a better solution for this problem and if my solution has any pitfalls, so please do critique and provide feedback.

This was a post from Alexandre Juca, A software Engineer working at a wonderful company called Next Solutions based in Luanda/Angola.

Image of Quadratic

Free AI chart generator

Upload data, describe your vision, and get Python-powered, AI-generated charts instantly.

Try Quadratic free

Top comments (0)