Testing macro exception

I have a macro that can raise but I am having trouble testing it. I tried the following thinking it would work, but doesn’t seem to. Any help on how to test this at compile time?

assert_raise ArgumentError, fn ->
  Code.eval_quoted(quote do
    defmodule MyMod do
      use MyMacro
      my_macro_that_will_raise
    end
  end)
end

I use these helpers for such things first of all:

You’d use them like (if I remember right, not looking at code ^.^ be sure to import CompileTimeAssertions at the top of your test file):

assert_compile_time_raise %ArgumentError{}, fn ->
  defmodule MyMod do
    use MyMacro
    my_macro_that_will_raise
  end
end

EDIT: I should probably rip it out into a standalone library sometime…

4 Likes

I know I’m resurrecting an old thread here, but I’ve noticed that this isn’t necessary anymore? At least, assert_raise seems to work just fine if I use a macro in assert_raise(ArgumentError, fn -> macro_that_raises() end). Has this changed since July 2017 or are there some cases for which assert_raise works and others for which it doesn’t?

It should still be as far as I know? Anything that raises at compile-time need to be eval’d like the above.

Do you have a case where it doesn’t? I’d love to test. :slight_smile:

I thought I had an example, but I didn’t. The distinction between compile time and … after compile time was unclear to me.

defmacro will_raise() do
  raise "raises at compile time"
end

vs

defmacro will_raise() do
  quote do
    raise "will raise normally"
  end
end

Yep, the first is compile-time and the second is run-time, usually, the second one could potentially become compile-time as well depending on what else is being done and where. :slight_smile: