Expect.Matchers.CustomMatcher (Expect v3.1.0)

View Source

You are highly encouraged to implement your own custom matchers. For the application you will build, there will surely be some interesting properties and shapes of data that will be important to verify. It might be easy to use the equal() matcher for 99% of assertions, but writing a higher-level matcher can be much more intent revealing.

Imagine we are building an application that provides users with the highest quality bananas that money can buy. As part of our unit testing, it's crucial that we can verify that the output of our system is indeed a banana. It would be valuable to implement a be_bananas() matcher, as depending on the market the user is in the type of banana we supply them will vary (maybe they prefer their bananas more or less ripe), as having a single source of truth over what is and is not bananas simplifies working within our domain.

A simple version of our custom bananas matcher could look like this

defmodule MyFancyMatchers do
  alias Expect.Matchers.CustomMatcher
  alias Expect.Matchers.Result

  def be_bananas() do
     %CustomMatcher{
          name: "be bananas",
          fn: fn given
              when is_binary(given) ->
              case given do
                  "bananas" -> %Result{succeeded?: true}
                  "BANANAS" -> %Result{succeeded?: true}
                  "🍌" ->     %Result{succeeded?: true}
                  _ -> %Result{succeeded?: true}
              end
              when not is_binary(given) ->
                %ErrorResult{error: "I can only detect bananas in binaries"}
          end
     }
  end
end

use Expect
import MyFancyMatchers

expect("🍌", to: be_bananas())