Search code examples
testingelixirex-unit

ExUnit without assert/refute, relying solely on pattern matching?


I'm testing the return value of a function. Which of the two is the preferred way?

test "extra verbose, using assert" do
  {:error, reason} = MyModule.my_fun
  assert reason == :nope
end

test "using pattern matching only" do
  {:error, :nope} = MyModule.my_fun
end

I like the first one because, I don't now, a test needs an assert statement and the error message when running the test is more descriptive. Otoh, a MatchError with line number should also be enough.


Solution

  • You can use assert with = to get both an assert and a more descriptive error message, and with just one line of code:

    assert {:error, :nope} = MyModule.my_fun
    

    Unlike with ==, you can use any pattern on the LHS, although in this case, = can be replaced with == since the LHS is both a valid pattern and value.

    On failure, you'll get an error message that's better than just doing the pattern matching without the assert, e.g.

      1) test the truth (MTest)
         test/m_test.exs:10
         match (=) failed
         code:  {:error, :nope} = MyModule.my_fun()
         right: {:error, :nop}
         stacktrace:
           test/m_test.exs:11: (test)