[][src]Crate httpmock

httpmock is a Rust library that allows you to mock HTTP services in your tests.

Features

  • Provides a full-blown HTTP mock server with HTTP/1 and HTTP/2 support.
  • A fully asynchronous core with synchronous and asynchronous APIs.
  • Compatible with all major asynchronous executors and runtimes.
  • Built-in request matchers with support for custom request matchers.
  • Parallel test execution by default.
  • A standalone mode with an accompanying Docker image.

Getting Started

Add httpmock to Cargo.toml:

[dev-dependencies]
httpmock = "0.4.0"

You can then use httpmock in your tests like shown in the example below:

extern crate httpmock;

use httpmock::Method::{GET};
use httpmock::{Mock, MockServer, MockServerRequest, Regex};
use isahc::{get};

#[test]
fn example_test() {
    // Start a local mock server for exclusive use by this test function.
    let mock_server = MockServer::start();

    // Create a mock on the mock server. The mock will return HTTP status code 200 whenever
    // the mock server receives a GET-request with path "/hello".
    let search_mock = Mock::new()
        .expect_method(GET)
        .expect_path("/hello")
        .return_status(200)
        .create_on(&mock_server);

    // Send an HTTP request to the mock server. This simulates your code.
    // The mock_server variable tis being used to generate a mock server URL for path "/hello".
    let response = get(mock_server.url("/hello")).unwrap();

    // Ensure the mock server did respond as specified above.
    assert_eq!(response.status(), 200);
    // Ensure the specified mock responded exactly one time.
    assert_eq!(search_mock.times_called(), 1);
}

API Usage

Each test usually creates its own local MockServer using MockServer::start. This creates a lightweight HTTP server that runs on its own port. This way tests do not conflict with each other.

You can use the Mock structure to specify and create mocks on the mock server. It provides you all supported mocking functionality.

Request Matching and Responses

Other than many other libraries httpmock does not require you to learn a DSL-like API to specify mock behaviour. Instead, httpmock provides you a fluent builder API that clearly separates request matching and response attributes by using the following naming scheme:

With this naming scheme users can benefit from IDE autocompletion to find request matchers and response attributes mostly without even looking into documentation.

If a request does not match at least one mock, the server will respond with an error message and HTTP status code 404 (Not Found).

Sync / Async

The internal implementation of httpmock is fully asynchronous. It provides you a synchronous and an asynchronous API though. If you want to schedule awaiting operations manually, then you can use the async variants that exist for every potentially blocking operation. For example, there is MockServer::start_async as an asynchronous counterpart to MockServer::start and Mock::create_on_async for Mock::create_on.

Parallelism

To balance execution speed and resource consumption, MockServers are kept in a server pool internally. This allows to run multiple tests in parallel without overwhelming the executing machine by creating too many HTTP servers. A test will be blocked if it tries to use a MockServer (e.g. by calling MockServer::new()) while the server pool is empty (i.e. all servers are occupied by other tests). To avoid TCP port binding issues, MockServers are never recreated but recycled/resetted. The pool is filled on demand up to a predefined maximum number of 25 servers. You can change this number by setting the environment variable HTTPMOCK_MAX_SERVERS.

Examples

Fore more examples, please refer to this crates test directory.

Debugging

httpmock logs against the log crate. For example, if you use the env_logger backend, you can activate debug logging by setting the RUST_LOG environment variable to httpmock=debug.

Standalone Mode

You can use httpmock to run a standalone mock server that is available to multiple applications. This can be useful if you are running integration tests that involve both, real and mocked applications.

Docker

Altough you can build the mock server in standalone mode yourself, it is easiest to use the Docker image from the accompanying Docker image. Please refer to the documentation on Docker repository.

API Usage

To be able to use a standalone server from your tests, you need to change how an instance of the MockServer structure is created. Instead of using MockServer::new(), you need to connect to a remote server by using one of the connect methods (such as MockServer::connect("localhost:5000") or MockServer::connect_from_env()). Therefore, tests that use a local mock server do only differ in one line of code from tests that use a remote server. Otherwise, both variants are identical.

use httpmock::{MockServer, Mock};
use isahc::get;

#[test]
fn simple_test() {
    // Arrange: Create a mock on a test local mock server
    let mock_server = MockServer::connect("some-host:5000");

    let search_mock = Mock::new()
        .expect_method(GET)
        .expect_path("/hello")
        .return_status(200)
        .create_on(&mock_server);

    // Act: Send an HTTP request to the mock server (simulates your software)
    let response = get(mock_server.url("/hello")).unwrap();

    // Assert: Ensure there was a response from the mock server
    assert_eq!(response.status(), 200);
    assert_eq!(search_mock.times_called(), 1);
}

Parallelism

Tests that use a remote mock server are executed sequentially by default. This is in contrast to tests that use a local mock server. Sequential execution is achieved by blocking all tests from further execution whenever a test requires to connect to a busy mock server.

Limitations

At this time, it is not possible to use custom request matchers in combination with remote mock servers. It is planned to add this functionality in future though.

Examples

Fore more examples on how to use a remote server, please refer to this crates test directory.

License

httpmock is free software: you can redistribute it and/or modify it under the terms of the MIT Public License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MIT Public License for more details.

Modules

standalone

Structs

HttpMockConfig

Holds server configuration properties.

Mock

Represents the primary interface to the mock server.

MockRef

Represents a reference to the mock object on a MockServer. It can be used to spy on the mock and also perform some management operations, such as deleting the mock from the MockServer.

MockServer

Enums

Method

Represents an HTTP method.

Type Definitions

MockServerRequest
Regex

Refer to regex::Regex.