Love the pipe operator? Miss them in tests with ExUnit when the result is derived from a pipeline of operations necessitating an intermediate variable, like result? I did…

typical test assertion (no pipe operator)

defmodule AdderTest do
  test "add" do
    result =
      1..3
      |> Enum.map(& &1 * 2) # [2, 4, 6]
      |> Adder.add(1) # [3, 5, 7]

    assert result == [3, 5, 7]
  end
end

verbose (with pipe)

We can employ an anonymous function (lambda). NOTE: invoked with dot-syntax

defmodule AdderTest do
  test "add" do
    1..3
    |> Enum.map(& &1 * 2)
    |> Adder.add(1)
    |> (fn result -> assert result == [3, 5, 7] end).()
  end
end

terse (with pipe)

This uses Elixir’s & (capture operator) to keep things concise

defmodule AdderTest do
  test "add" do
    1..3
    |> Enum.map(& &1 * 2)
    |> Adder.add(1)
    |> (& assert &1 == [3, 5, 7]).()
  end
end

an option for those that use Elixir’s formatter

If you or your team use Elixir’s formatter, then you’re going to end up with something like the following where the nice whitespace that gives your arguments some room to breathe is removed. One thing that I’ve done is add two enhancement functions (using a macros) into test/test_helper.exs that become available to tests by invoking use TestHelper

defmodule AdderTest do
  test "add" do
    1..3
    |> Enum.map(& &1 * 2)
    |> Adder.add(1)
    |> (&assert(&1 == [3, 5, 7])).() # 🤮
  end
end

Here’s what we can do

# test/test_helper.exs

ExUnit.start()

defmodule TestHelper do
  defmacro __using__(_opts) do
    quote do
      import ExUnit.Assertions, only: [assert: 1]

      # we can name this whatever we'd like,
      # but "is" makes sense to me in most cases
      # 👇
      def is(result, expectation) do
        assert result == expectation
        result # 👈 allows us to continue chaining assertions in a pipeline
      end

      # this one allows us to make more complex assertions
      # e.g., asserting that a nested key is of a particular value
      def has(result, assertion) when is_function(assertion) do
        assert assertion.(result) == true
        result
      end
    end
  end
end

# test/adder_test.exs

defmodule AdderTest do
  use TestHelper # 👈 included here

  test "add" do
    1..3
    |> Enum.map(& &1 * 2)
    |> Adder.add(1)
    |> is([3, 5, 7]) # 👈 used here
    |> has(&List.last(&1) == 7) # 👈 and here (chained)
  end
end