I was banging my head against a simple elixir test this morning. It's a test that's been in my code for months and that never worked for some reason. This is a boiled down example:
defmodule RaiseTest do
def testraise do
raise "This is an error"
defmodule RaiseTestTest do
test "assert_raise works" do
assert_raise(RuntimeError, RaiseTest.testraise )
1) test assert_raise works (RaiseTestTest)
** (RuntimeError) This is an error
(raise_test) lib/raise_test.ex:4: RaiseTest.testraise/0
Finished in 0.03 seconds (0.03s on load, 0.00s on tests)
1 tests, 1 failures
My error was finally pointed out to me this morning on the elixir list and opened my eyes to a consistent flaw in my thinking about elixir. The fix of course is to actually provide a function to assert_raise, what I was actually providing was an expression that could return anything.
test "assert_raise works" do assert_raise(RuntimeError, fn -> RaiseTest.testraise end ) end
The key misunderstanding in my head was that function when used in the elixir context actually maps to what I think of as a function reference from my years of C programming. Module functions return expressions which can be anything. The test failed because it was calling TestRaisetest to see if it returned a function it could use in the test. When an elixir function requires a "function" as an argument, it really means a closure that can be executed.