Change Log

0.16.0 (2025-06-03)

No new functionality in this release but an update to the CI/CD versions and bugfix.

Patch should continue to work on older versions of Elixir but CI/CD runner versions have been updated to re-enable CI/CD.

Thanks to Steve Cohen who reported a bug where patch would incorrectly handle multiple export attributes. This bug has been fixed and a test added.

Bugfixes

Breaking Changes

0.15.0 (2024-12-27)

No new functionality in this release but an update to the supported versions.

Thanks to Moosieus Patch now compiles cleanly on Elixir 1.9+ with the removal of some outdated language constructs in favor of more modern constructs.

0.15.0 removes support for Elixir 1.7 (released in July of 2018) and 1.8 (released in January of 2019). This version also adds 1.17 and 1.18 to the support matrix.

If you are still running on 1.7 or 1.8 you should continue to use the 0.14.0 release, if you require ongoing support you should open an issue to discuss.

Improvements

Breaking Changes

0.14.0 (2024-10-15)

Changes where mocks are evaluated to prevent misuse and allow for common patterns that were not previously supported.

Pre-0.14.0 mocks would be intercepted by the Patch.Mock.Server and the mock value would be calculated by the server. This works for most cases, but has surprising behavior when the mock function cares about the process executing the function. Consider the following example.

defmodule ExampleTest do
use ExUnit.Case
use Patch
test "example" do
patch(Example, :get_pid, fn -> self() end)
assert Example.get_pid() == self()
end
end

This would fail in pre-0.14.0 because the fn -> self() end would be executed by the Patch.Mock.Server and the pid returned would be the pid for the Patch.Mock.Server and not the caller's pid as the test author might expect.

0.14.0 changes this behavior and now will execute the fn -> self() end in the caller and return the expected result.

This also makes it much more difficult to address the Patch.Mock.Server directly, which is generally discouraged as this server is an implementation detail and should only be addressed by the Patch code itself. This should prevent a class of errors and confusing bugs caused by tests accidentally capturing the pid of, monitoring, or linking to the Patch.Mock.Server

Improvements

Breaking Changes

0.13.1 (2024-05-02)

Minor bugfix to correct an issue with negative step ranges in String.slice/2 raised by

Bugfixes

0.13.0 (2023-10-17)

Added the ability to control how Patch functions are imported in test modules. Added the ability to listen/3 without a target, useful when a process is spawned by another process and the spawning of that process is not within the testing boundaries.

Features

Breaking Changes

None

0.12.0 (2022-02-08)

Fixed a bug where defective mock functions would be incorrectly classified as unmocked functions, this would engage the passthrough functionality and call the original function.

If a passthrough mock function's implementation raised BadArityError or FunctionClauseError it would be incorrectly classified by the mock system as an unmocked function. The internal mechanisms have been updated to differentiate between exceptions arising directly from the function call vs exceptions in caused by executing the code in the function.

Added a new debug/0,1 facility that can be used to enable library level debugging in for a test function. This functionality can also be controlled by the :patch :debug configuration value.

Features

Bugfixes

Improvements

Breaking Changes

None

0.11.0 (2022-01-21)

New private/2 macro to assist with using exposed functions.

Introduces "Tagged Histories" to prevent a race condition that causes confusing output when using Patch assertions.

Race Condition Description:

  1. Assertion function checks the history for a matching call, none is found.
  2. Assertion function pulls the history to format an error message.

Between 1 and 2 if a matching call arrived then the assertion would fail but print out a message with a matching call.

This race condition has been defeated by only pulling the history once and using it for both checking for the existence of a call and formatting an error message.

In addition a bunch of code that was littering Patch.Mock has been moved to a more appropriate location by introducing the concept of a "Tagged History" (Patch.Mock.History.Tagged)

Tagged Histories have the same entries as a History. One generates a Tagged History from a History and some matching criteria. Ever entry in the Tagged History is the entry from the History tagged with a boolean that indicates whether or not it matched the construction criteria.

Features

Bugfixes

Breaking Changes

None

0.10.2 (2022-01-20)

Major fix to Patch.Mock.Code.Transforms.Remote. Previously this transform completely ignored remote calls. This would cause an issue when one of the arguments to the remote call was itself a local call. This has been corrected and the Patch.Test.User.Patch.LocalCallTest was updated to prevent regressions.

Bugfixes

0.10.1 (2021-12-07)

Minor fix to .formatter.exs. Exported format options were not being honored because of a typo, export is the honored key but exports was being used.

Improvements

Bugfixes

0.10.0 (2021-12-05)

Changes how function patches work by introducing "Stacked Callables."

Stacked Callables are a large new feature that builds on the passthrough evaluation feature introduced in v0.9.0.

Chapter 2 of the Guidebook has a new section that explains this design in detail.

Breaking Changes

Improvements

Features

Deprecations

0.9.0 (2021-12-02)

Changes how function patches work so that the test author can only patch out a subset of function calls.

Breaking Changes

Improvements

0.8.2 (2021-11-12)

Bugfix for handling module attributes in Call Assertions.

Bugfixes

0.8.1 (2021-11-12)

Bugfix for handling modules with aggregate compile attributes. This fixes a codegen bug introduced in 0.8.0.

Bugfixes

0.8.0 (2021-11-11)

Improved call assertion to use full pattern matching. Pattern matching works like ExUnit's assert_receive/3 and assert_received/2. Unpinned variables will be bound when asserting.

Breaking Changes

Improvements

Features

Bugfixes

Removals

0.7.0 (2021-10-21)

Support for call counts in assertions. assert_called/1 and refute_called/1 are unchanged.

Breaking Changes

None

Improvements

Features

Deprecations

0.6.1 (2021-10-17)

Minor release to improve the documentation and reduce the scope of imported symbols from Patch.Mock.Value.

Improvements

Removals

0.6.0 (2021-10-16)

Major internal refactor. This version removes meck as a dependency and implements a Patch specific replacement, Patch.Mock. This allows us to have a new set of functionality that no other mocking library for Elixir / Erlang has today.

Patch Mocks can now be said to obey a single simple rule, public or private, local or remote.

A patched function always returns the mock value to all callers.

Two new bits of functionality make this true.

  1. All calls, local or remote, end up intercepted and the mock value returned.
  2. Private functions can be mocked.

And as a bonus

  1. Private functions can be converted into public functions for direct testing.

Breaking Changes

Improvements

Features

Removals

0.5.0 (2021-09-17)

Better support for mocking erlang modules

Breaking Changes

None

Improvements

Bugfixes

0.4.0 (2021-08-09)

Support for working with Processes

Breaking Changes

None

Improvements

Features

0.3.0 (2021-07-12)

Support for replacing a module wholesale via the fake/2 function

Breaking Changes

None

Improvements

Features

0.2.0 (2021-03-03)

Removed Arity Limitations

Breaking Changes

None

Improvements

Features

0.1.2 (2021-01-28)

Increased Elixir Compatibility

Improvements

0.1.1 (2020-04-27)

Bugfix Release

Improvements

Bugfixes

0.1.0 (2020-04-21)

Initial Release

Breaking Changes

None

Improvements

Features