defmodule StructAssert do @moduledoc """ A useful tool for testing sturct and map in Elixir. """ @doc """ assert only a part of struct and map. defmodule MyStruct do defstruct a: 1, b: 1, z: 10 end defmodule Example use ExUnit.Case import StructAssert, only: [assert_subset?: 2] got = %MyStruct{} assert_subset?( got, %{ a: 1, b: 2 } ) end # code: assert_subset?(got, %{a: 1, b: 2}) # left: %{a: 1, z: 10, b: 1} # right: %{a: 1, z: 10, b: 2} """ defmacro assert_subset?(got, expect) do got_var_name = got |> Macro.expand(__ENV__) |> Macro.to_string expect_var_name = expect |> Macro.expand(__ENV__) |> Macro.to_string quote do import ExUnit.Assertions got_map = case unquote(got) do %_{} -> Map.from_struct(unquote(got)) %{} -> unquote(got) _ -> :error end expect = DeepMerge.deep_merge(got_map,unquote(expect)) assert got_map == expect, expr: "assert_subset?(#{unquote(got_var_name)}, #{unquote(expect_var_name)})", left: got_map, right: expect end end end