ExStub provides an easy way to stub a module and record the function calls on it.

Monthly Downloads: 8
Programming language: Elixir
License: MIT License

ExStub alternatives and similar packages

Based on the "Testing" category.
Alternatively, view ExStub alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of ExStub or a related project?

Add another 'Testing' Package



Build Status Hex.pm API Docs Coverage Status Inline docs

ExStub provides an easy way to stub a module and record the function calls on it.


Add ex_stub to your deps in mix.exs as a development dependency.

def deps do
  [{:ex_stub, "~> 0.1.0", only: :test}]


If you have a module in your original application like:

defmodule OriginalModule do
  def process(param), do: :original_process
  def another_method, do: :original_method

You can quickly create a stub copy of this module using defstub

use ExStub

defstub MyStub, for: OriginalModule do
  def process(true), do: :stubbed1
  def process(false), do: :stubbed2
  def process(1), do: :stubbed3

Now you can pass around MyStub instead of OriginalModule. When you invoke method from the created MyStub, if the method was stubbed it will call the stubbed version. Else the original version will be called.

MyStub.process(true) # returns :stubbed1
MyStub.process(false) # returns :stubbed2
MyStub.process(1) # returns :stubbed3

MyStub.process(20) # returns :original_process

MyStub.another_method # returns :original_method

Notice that Since we did not stub another_method, calling it on MyStub returns the original implementation. Also when calling MyStub.process(20) the original implementation is called since it failed pattern matching with our stub version of the method.

As a safety procedure, if you try to stub a method that is not found in the original module. ExStub will throw a compilation error telling you about the unexpected stubbed method.

defstub MyStub, for: OriginalModule do
def new_method(), do: :stubbed1

The following error will be thrown

** (RuntimeError) Cannot provide implementations for methods that are not in the original module
The def `{:new_method, 0}` is not defined in module `OriginalModule`

Recording method calls

All the functions called on the defstub created module will be recorded.

To get all the functions calls on YourModule module


To get all the :the_method function calls on YourModule

ExStub.Recorder.calls(YourModule, :the_method)

Alternativey, you can use assert_called in your unit tests:

The syntax is assert_called ModuleName.function_name(params)

# No parameters
assert_called ModuleName.function_name

# nil passed
assert_called ModuleName.function_name(nil)

# multiple parameters
assert_called ModuleName.function_name(1, 2)

Some more examples


# Passes since we called the function with [1]
assert_called MyStub.process(1)

# Fails since the parameters dont match
assert_called MyStub.process(1, 2)

# Fails since we did not call `another_method`
assert_called MyStub.another_method