Pattern matching on a map subset in ExUnit.Assertions.assert_received/2

I’m trying to figure out how to best implement this test case and I hit a wall with how I expected the pin operator to work. Here is a simplified version of the test case.

simple_map = %{simple: :data}

assert_received {:things_done, ^simple_map}

My issue is that the value sent back does not exactly match simple_map, but is another map with a bunch of extra stuff added to it that I don’t care about testing right here. I can solve it pretty easily like this:

simple_map = %{simple: :data}

assert_received {:things_done, received_map}
assert %{simple: :data} = received_map

but my issue is that I want to repeat this pattern a lot, the simple data actually has quite a few keys, and I don’t want to type out all the match criteria for every case because I expect it would be error prone. I’m trying to figure out a way to pattern match simple_map as a subset of received_map.

I see from the below linked mailing list thread that, as of 2016, the pin operator can’t help me here, because it is always doing a full equality check, not a pattern match. Are there any other tools for this case that I’m missing here? The feature I’d want would be something like this:

Kernel.subset?(base_map, extended_map)
def subset?(subset, full) when is_map(subset) and is_map(full) do
  Enum.all?(subset, fn {k, v} ->
    case Map.fetch(full, k) do
      {:ok, full_val} -> full_val == v
       :error -> false

Not sure if that applies to your case, but why not make several structs and compare them directly? All you would need are several construction functions (&YourStruct.from_map/1) and from then on you can leave the rest of the lifting to Elixir.

Of course, if you are interested in covering permutations of possible keys in a map that would not be practical.