patch v0.2.0 Patch View Source
Patch - Ergonomic Mocking for Elixir
Patch makes it easy to mock one or more functions in a module returning a value or executing custom logic. Patches and Spies allow tests to assert or refute that function calls have been made.
Patches
When a module is patched, the patched function will return the value provided.
assert "HELLO" = String.upcase("hello") # Assertion passes before patching
patch(String, :upcase, :patched_return_value)
assert :patched_return_value == String.upcase("hello") # Assertion passes after patching
Modules can also be patched to run custom logic instead of returning a static value
assert "HELLO" = String.upcase("hello") # Assertion passes before patching
patch(String, :upcase, fn s -> String.length(s) end)
assert 5 == String.upcase("hello") # Assertion passes after patching
Patching Ergonomics
patch/3
returns the value that the patch will return which can be useful for later on in the
test. Examine this example code for an example
{:ok, expected} = patch(My.Module, :some_function, {:ok, 123})
... additional testing code ...
assert response.some_function_result == expected
This allows the test author to combine creating fixture data with patching.
Asserting / Refuting Calls
After a patch is applied, tests can assert that an expected call has occurred by using the
assert_called
macro.
patch(String, :upcase, :patched_return_value)
assert :patched_return_value = String.upcase("hello") # Assertion passes after patching
assert_called String.upcase("hello") # Assertion passes after call
assert_called
supports the :_
wildcard atom. In the above example the following assertion
would also pass.
assert_called String.upcase(:_)
This can be useful when some of the arguments are complex or uninteresting for the unit test.
Tests can also refute that a call has occurred with the refute_called
macro. This macro works
in much the same way as assert_called
and also supports the :_
wildcard atom.
Spies
If a test wishes to assert / refute calls that happen to a module without actually changing the
behavior of the module it can simply spy/1
the module. Spies behave identically to the
original module but all calls and return values are recorded so assert_called and refute_called
work as expected.
Link to this section Summary
Functions
Asserts that the function has been called with any arity call
Patches a function in a module
Refutes that the function has been called with any arity call
Remove any mocks or spies from the given module
Spies on the provided module
Link to this section Functions
Asserts that the function has been called with any arity call
Patches a function in a module
The patched function will either always return the provided value or if a function is provided then the function will be called and its result returned.
Refutes that the function has been called with any arity call
Remove any mocks or spies from the given module
Spies on the provided module
Once a module has been spied on the calls to that module can be asserted / refuted without changing the behavior of the module.