Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom ExUnit assertions and pattern matching

Tags:

elixir

ex-unit

I'm writing a flexible, adapter-based error tracking library and provide a set of custom test assertion functions to make integration tests easier to work with.

I have something like

  # /lib/test_helpers.ex 

  ...

  @doc """
  Asserts specific exception and metadata was captured

  ## Example

      exception = %ArgumentError{message: "test"}
      exception |> MyApp.ErrorTracker.capture_exception(%{some_argument: 123})
      assert_exception_captured %ArgumentError{message: "test"}, %{some_argument: 123}
  """
  def assert_exception_captured(exception, extra) do
    assert_receive {:exception_captured, ^exception, ^extra}, 100
  end

Which will pass the exact exception to the assert_exception_captured, but it does not work when trying to pattern match on for example the struct of the exception.

I'd like to be able to do this

...
assert_exception_captured _any_exception, %{some_argument: _}

How can I make this work with pattern matching?

Much appreciated

like image 723
Tarlen Avatar asked Jan 28 '26 13:01

Tarlen


1 Answers

You'll need to use macros if you want to be able to pass in a pattern. This is how you can implement it with a macro:

defmacro assert_exception_captured(exception, extra) do
  quote do
    assert_receive {:exception_captured, ^unquote(exception), unquote(extra)}, 100
  end
end

Test:

test "greets the world" do
  exception = %ArgumentError{message: "test"}
  send self(), {:exception_captured, exception, %{some_argument: 123}}
  assert_exception_captured exception, %{some_argument: _}
end

Output:

$ mix test
.

Finished in 0.02 seconds
1 test, 0 failures
like image 115
Dogbert Avatar answered Jan 31 '26 10:01

Dogbert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!