Is there a good way to test an exception is raised in a __before_compile__?
For example
defmodule MustBeValid do
defmacro __using__(is_valid?) do
quote do
@is_valid unquote(is_valid?)
@before_compile unquote(__MODULE__)
end
end
defmacro __before_compile__(env) do
unless Module.get_attribute(env.module, :is_valid) do
raise "invalid"
end
end
end
defmodule WillFail do
use MustBeValid, false
end
You can eval/compile files at runtime. Just build a fixture and test against it.
You should change raise "invalid" to something a bit more helpful tho. maybe: raise CompileError, description: "missing attribute", file: __ENV__.file, line: __ENV__.line
defmodule MustBeValidTest do
@fixture_file Path.join(["fixtures", "must_be_valid.ex"]
@external_resource @fixture_file
use ExUnit.Case
test "CompileError" do
assert_raise CompileError, "Some Helpful Info", fn() ->
Code.eval_file(@fixture_file)
end
end
end
test "CompileError" do
assert_raise CompileError, "Some Helpful Info", fn() ->
ast = quote do
defmodule WillFail do
use MustBeValid, false
end
end
Code.eval_quoted(ast, []. __ENV__)
end
end
If you want to test a regular macro and you simply invoke it inside the test, then the error will come when the test is expanded, before the tests even run, which is not what you want. Then you have to either put the macro inside a module, as I suggested, or use eval, as @michalmuskala suggested.