Patch (patch v0.4.0) 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.

Using Patch is as easy as adding a single line to your test case.

use Patch

After this all the patch functions will be available, see the README and function documentation for more details.

Link to this section Summary

Functions

Asserts that the function has been called with any arity call

Fakes out a module with an alternative implementation.

Convenience function for updating the state of a running process.

Starts a listener process.

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

Link to this function

assert_any_call(module, function)

View Source

Specs

assert_any_call(module :: module(), function :: atom()) :: nil

Asserts that the function has been called with any arity call

Link to this macro

assert_called(arg)

View Source (macro)
Link to this function

fake(real_module, fake_module)

View Source

Specs

fake(real_module :: module(), fake_module :: module()) :: :ok

Fakes out a module with an alternative implementation.

The real module can still be accessed with real/1.

For example, if your project has the module Example.Datastore and there's a fake available in the testing environment named Example.Test.InMemoryDatastore the following table describes which calls are executed by which code before and after faking with the following call.

fake(Example.Datastore, Example.Test.InMemoryDatastore)
Calling CodeResponding Module before fake/2Responding Module after fake/2
Example.Datastore.get/1Example.Datastore.get/1Example.Test.InMemoryDatastore.get/1
Example.Test.InMemoryDatastore.get/1Example.Test.InMemoryDatastore.get/1Example.Test.InMemoryDatastore.get/1
real(Example.Datastore).get/1(UndefinedFunctionError)Example.Datastore.get/1

The fake module can use the renamed module to access the original implementation.

Link to this function

inject(target, keys, value)

View Source

Specs

inject(target :: GenServer.server(), keys :: [term(), ...], value :: term()) ::
  term()

Convenience function for updating the state of a running process.

Uses the Access module to traverse the state structure according to the given keys.

Structs have special handling so that they can be updated without having to implement the Access behavior.

Link to this function

listen(tag, target, options \\ [])

View Source

Specs

listen(
  tag :: Patch.Listener.tag(),
  target :: Patch.Listener.target(),
  options :: Patch.Listener.options()
) :: {:ok, pid()} | {:error, :not_found}

Starts a listener process.

When used on a named process, this is sufficient to begin intercepting all messages to the named process.

When used on an unnamed process, the process that is spawned will forward any messages to the caller and target process but any processes holding a reference to the old pid will need to be updated.

inject/3 can be used to inject a listener into a running process.

Link to this function

patch(module, function, mock)

View Source

Specs

patch(module :: module(), function :: atom(), mock) :: mock
when mock: (... -> any())
patch(module :: module(), function :: atom(), return_value) :: return_value
when return_value: term()

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.

Specs

real(module :: module()) :: module()
Link to this function

refute_any_call(module, function)

View Source

Specs

refute_any_call(module :: module(), function :: atom()) :: nil

Refutes that the function has been called with any arity call

Link to this macro

refute_called(arg)

View Source (macro)

Specs

restore(module :: module()) :: :ok

Remove any mocks or spies from the given module

Specs

spy(module :: module()) :: :ok

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.