Skip to content

Instantly share code, notes, and snippets.

@codingfoo
Last active July 19, 2017 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codingfoo/284c6892971316e5f68c3d0d540d5740 to your computer and use it in GitHub Desktop.
Save codingfoo/284c6892971316e5f68c3d0d540d5740 to your computer and use it in GitHub Desktop.
Proof of concept for Elixir add functions to a mock library in tests
1. To pull in functions from multiple Tests a different before_compile hook needs to be registered for each test module
2. To add mocks to multiple mock modules, a attribute needs to be set up for each mock
ExUnit.start
defmodule MockUtil do
defmacro __using__(_opts) do
quote do
defmacro __using__(_env) do
test_module = __MODULE__
mock_module = __CALLER__.module
|> Atom.to_string
|> String.downcase
|> String.split(".")
|> tl
name = "#{mock_module}_functions_attr" |> String.to_atom
quote do
unquote(test_module).unquote(name)()
end
end
end
end
defmacro add_mock_function( module, do: block ) do
mock_module = Macro.expand_once( module, __CALLER__)
|> Atom.to_string
|> String.downcase
|> String.split(".")
|> tl
test_module = __CALLER__.module
functions_attribute = "#{mock_module}_functions_attr" |> String.downcase |> String.to_atom
first_time? = Module.get_attribute test_module, functions_attribute
Module.register_attribute test_module,
functions_attribute,
accumulate: true, persist: false
Module.put_attribute test_module, functions_attribute, block
if first_time? == nil do
ast = {:@, [], [{functions_attribute, [], test_module}]}
name = "#{mock_module}_functions_attr" |> String.to_atom
quote do
defmacro unquote(name)(), do: unquote(ast)
end
end
end
end
defmodule Test do
use ExUnit.Case
use MockUtil
MockUtil.add_mock_function Mock do
def foo do
"Inside foo."
end
end
test "Register function adds foo function" do
assert "Inside foo." == Mock.foo
end
MockUtil.add_mock_function Mock do
def bar do
"Inside bar."
end
end
test "Register function adds bar function" do
assert "Inside bar." == Mock.bar
end
MockUtil.add_mock_function MockAgain do
def baz do
"Inside bar."
end
end
test "Register function adds baz function" do
assert "Inside bar." == MockAgain.baz
end
end
defmodule Mock do
use Test
end
defmodule MockAgain do
use Test
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment