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
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