Mocks and Explicit Contracts logo

Mocks and Explicit Contracts

Free

Guidelines for explicit contracts and mocks in Elixir testing

FreeFree tier
Type
Open Source
Company
Plataformatec

About Mocks and Explicit Contracts

A blog post by José Valim (co-creator of Elixir) that provides guidelines for using mocks in testing by emphasizing explicit contracts and dependency configuration. It argues that mocks should be used as nouns (simulated entities) rather than verbs (action of mocking), and demonstrates how to decouple application code from specific HTTP clients using Elixir's configuration system. The approach replaces mocking the underlying HTTP client with environment-specific implementations (e.g., sandbox, in-memory, HTTP client) to achieve cleaner, more maintainable tests that can run concurrently. The post later inspired the Mox library for Elixir.

Key Features

Emphasizes explicit interfaces between components via configuration
Showcases environment-specific implementations (sandbox, in-memory, HTTP client)
Critiques global mocking that couples to specific HTTP clients
Advocates for mocks as nouns (simulated entities) not verbs
Directly led to the creation of the Mox library for Elixir

Pros & Cons

Pros
  • Avoids coupling tests to specific HTTP client implementations
  • Allows tests to run concurrently (no global state changes)
  • Encourages clean separation of concerns via configuration
  • Provides a practical, language-specific example (Elixir)
  • Foundation for the well-regarded Mox library
Cons
  • Not a tool itself – requires manual implementation of the pattern
  • Assumes use of Elixir's configuration system (not portable to other languages without adaptation)
  • Does not cover all mocking scenarios (focuses on external API example)

Best For

Testing external API clients (e.g., Twitter) without hitting real endpointsDecoupling application logic from specific HTTP client librariesEnabling concurrent test suites in Elixir by avoiding global mockingDesigning modular code with explicit dependencies

FAQ

What is the main problem with mocking HTTPClient directly?
It couples your application to that particular HTTP client; changing the client later breaks tests even if behavior is unchanged. It also uses global mocking, preventing concurrent test execution in Elixir.
What solution does the article propose?
Instead of mocking the HTTP client, define an explicit interface for your service (e.g., Twitter API) and configure different implementations per environment (dev, test, prod) using Elixir's Application.get_env/2.
How does the approach improve test concurrency?
By avoiding global mocking (which changes modules globally), the environment-based configuration allows each test to use its own injection, enabling the test suite to run concurrently.
What library was later released based on this article?
Mox, an Elixir library for defining mocks with explicit contracts, following the guidelines in this post.