Search code examples
elixirex-unit

Use ExUnit.Assertions inside macro


I have written a small macro for test cases.

    defmodule ControllerTest do
      @required [:phone, :country]
      defmacro create(fields) do
        quote do
          without = length(unquote(@required) -- unquote(field)
          if without != 0 do
            Enum.map(unquote(@required), fn(field) ->
              member = Enum.member?(unquote(fields), field)
              if member == false do
                expected_error = String.to_atom(Atom.to_string(field) <> " " <> "can't be blank")
                expected = {:error, expected_error}
               assert expected == {:error, expected_error} 
              end
            end)
          else
            expect = {:success, "Record created"}
            assert expect == {:success, "Record created"}
          end
        end
      end
     end

Its working fine without assert. But when I try to use assert it says assert is undefined. I have try import ExUnit.Assertions inside the module but still the same assert is undefined.

What will be the possible solution for this to use assert inside the macro?

Thanks


Solution

  • You need to add the import inside the quote before you use assert. Adding it before quote will not make assert available inside quote.

    defmacro create(fields) do
      quote do
        import ExUnit.Assertions
        without = ...
        ...
      end
    end
    

    Also, your Enum.map can be simplified like this:

    for field <- unquote(@required), field not in unquote(fields) do
      expected_error = String.to_atom(Atom.to_string(field) <> " " <> "can't be blank")
      expected = {:error, expected_error}
      assert expected == {:error, expected_error} 
    end