Fundamental Concepts
Why Mocking HTTP Services?
Many applications rely on HTTP-based endpoints like REST APIs. During testing, developers often mock HTTP communication to avoid external dependencies. This is typically done by replacing the real HTTP client with a test-specific stub, allowing tests to focus on internal logic without executing actual HTTP requests.
However, this approach leaves a significant portion of the client code untested, including whether it sends correct HTTP requests and is able to handle real HTTP responses, network issues, or error responses.
httpmock
bridges this gap by letting your tests use real client code to send requests to a mock server instead of the actual service. The mock server is set up to respond according to the specific needs of each test scenario.
Mocking Basics
httpmock
allows you to configure mock servers for a test scenario by calling its mock
method:
The mock
method creates a
rule on the mock server that responds to HTTP requests when the request marches all specified criteria.
The when
variable is a builder-like structure that specifies when the mock server should respond.
In the example, it is configured to respond to requests with the path /hello
(e.g., GET http://localhost:8080/hello
).
Since no additional criteria are provided, the mock server will respond to any request with the path /hello
,
regardless of the HTTP method (e.g., GET
, POST
) or request body content.
The then
variable specifies the response details when a request meets the defined criteria. In the example,
it sets the response to return a status code 200 (OK)
without body, headers, or any other value.
If a request does not meet all specified criteria, the mock server will automatically respond with status code 404 (Not Found)
.
There is no limit to the number of mocks you can create on a mock server. You can set up as many as needed for your test scenarios.
Sync and Async API
The internal implementation of httpmock
is entirely based on asynchronous communication. However, it provides both, a synchronous (blocking) and an asynchronous
(non-blocking) API. Asynchronous operations can be identified by the API’s method signatures, typically ending with _async
(such as mock_async
as the asynchronous variant of the method mock
).
This pattern can be found throughout the entire API of httpmock
.
Supported Async Executors
httpmock
is designed to be executor-agnostic. Our CI/CD pipeline includes dedicated tests to verify compatibility with at least the following async executors:
Test Execution and Pooling
When you initialize MockServer
instances in your tests (e.g., using
MockServer::start()
), httpmock
allocates a mock server from a global server pool for exclusive use by your test.
This ensures that no other test can use the same mock server instance during test execution.
Once the test ends, either successfully or with a failure, the mock server instance is automatically returned to the global pool and made available for other tests. The library automatically manages all cleanup of the mock server.
The default pool limit is set at 25 mock servers to avoid overloading the host system.
Although this limit is conservative, many host machines can handle additional servers.
Increasing this limit may not be necessary, depending on the parallelism settings of your test execution.
You can modify the pool size by setting the HTTPMOCK_MAX_SERVERS
environment variable.
When the global mock server pool is empty and all servers are in use, any test attempting to instantiate a mock server will automatically be blocked until a server becomes available again.
Parallelism With Remote Mock Servers
httpmock
allows mock servers to be executed in standalone mode, where each server runs in its own process,
typically launched as a separate binary. Tests can connect to these “remote” mock servers using
MockServer::connect
,
MockServer::connect_async
,
and other MockServer functions prefixed
with connect
.
When using any connect function in tests, the parallelism is set to 1, allowing only one test to access the remote server at a time. This ensures that there are no conflicts with other tests during execution.
Environment Variables
Rust Tests
HTTPMOCK_MAX_SERVERS
: Sets the maximum number of mock servers in the global mock server pool.HTTPMOCK_REQUEST_HISTORY_LIMIT
: Mock servers keep a history of all requests that have been received in a test. The history works like a ring buffer, removing the oldest request from the history once it reaches the configured maximum. The request history is used for call assertions to verify that a request has been received that matches certain criteria, such as inMock::assert
. By default, this number is set to 100.HTTPMOCK_HOST
/HTTPMOCK_PORT
: Sets the hostname/port that should be used connect to remote mock servers when usingMockServer::connect_from_env()
orMockServer::connect_from_env_async()
.
Standalone Binary:
HTTPMOCK_EXPOSE
: If set to1
, the mock server will be configured to accept external connections (binds to0.0.0.0
). Otherwise, only connections from your local machine will be accepted.HTTPMOCK_MOCK_FILES_DIR
: The location where the mock server should look for mock definition files (YAML format).HTTPMOCK_DISABLE_ACCESS_LOG
: When set to0
, the mock server will not log incoming requests.
Cargo Features
The crate provides the following Cargo features:
cookies
: Enables request matchers for parsing and matching values in cookiesproxy
: Enables the mock server to function as a proxy serverrecord
: Enables functionality to record requests and responses (most useful in combination with theproxy
feature). Enables reading mock specifications from YAML files (e.g., recorded responses)https
: Enables the mock server to provide a unified port for both, HTTP and HTTPS. Attention: This feature is experimental. Hence, there are no guarantees that this feature will work.http2
: Enables mock server support for HTTP2standalone
: Enables standalone moderemote
: Allows to connect to remote (standalone) mock serversremote-https
: Enables communication to remote (standalone) mock servers viaHTTPS
color
: enables colorful output in standalone mode
For example, the command cargo test --features=remote
enables the functionality in your tests to communicate with remote standalone mock servers.