HTTP mocking library for Rust

Advanced verification and debugging support

httpmock

HTTP mocking library for Rust.

Documentation · Crate · Report Bug · Request Feature · Changelog

Features

  • Simple, expressive, fluent API.
  • Many built-in helpers for easy request matching.
  • Parallel test execution.
  • Extensible request matching.
  • Fully asynchronous core with synchronous and asynchronous APIs.
  • Advanced verification and debugging support.
  • Network delay simulation.
  • Support for Regex matching, JSON, serde, cookies, and more.
  • Standalone mode with an accompanying Docker image.
  • Support for mock specification based on YAML files.

Getting Started

Add httpmock to Cargo.toml:

You can then use httpmock as follows:

The above example will spin up a lightweight HTTP mock server and configure it to respond to all GET requests to path /translate with query parameter word=hello. The corresponding HTTP response will contain the text body Привет.

Usage

See the reference docs for detailed API documentation.

Examples

You can find examples in the httpmock test directory. The reference docs also contain a lot of examples. There is an online tutorial as well.

Standalone Mock Server

You can use httpmock to run a standalone mock server that is executed in a separate process. There is a Docker image available at Dockerhub to get started quickly.

The standalone mode allows you to mock HTTP based APIs for many API clients, not only the ones inside your Rust tests, but also completely different programs running on remote hosts. This is especially useful if you want to use httpmock in system or end-to-end tests that require mocked services (such as REST APIs, data stores, authentication providers, etc.).

Please refer to the docs for more information

File Based Mock Specification

For convenience, the standalone mode also allows you to use YAML files for mock specification, so you do not need to use Rust or any other programming language at all. The mock specification file schema is very similar to the httpmock Rust API, so it's easy to jump between the two. Please find an example mock specification file here.

Please refer to the docs for more information.

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.

Issues

Collection of the latest Issues

sr-gi

sr-gi

0

I was wondering whether it is currently possible to simulate a MockServer being unreachable so client functionality that deals with such issues can be tested.

I can kind of replicate this by just starting the server whenever I'd like it to be reachable, but stopping it and starting it again using the same address / port is what seems tricky.

sr-gi

sr-gi

enhancement
1

I've noticed something missing that would be, IMHO, pretty useful for testing external clients agains mocked servers.

That's sharing variables between requests and responses. For instance, let's say we have a client posting some JSON data to a server, and the server may reply based on that data. The when clause should be able to expose the request data so the then clase can read it and act accordingly.

ufoscout

ufoscout

enhancement
4

With my team we are evaluating httpmock; it really looks like a great project. Anyway, our test compile-time increased substantially due to its number of dependencies. Would it maybe be possible to reduce the dependencies using cargo features? For example, I guess isahc and some other "client-side" libraries are used only with a remote server; could they be made optional and enabled with a remote feature?

pinkforest

pinkforest

enhancement
0

Error and/or Documentation Error and/or Relative Path Handling Error

I was using a relative path for the fn call directly per doc example for Then::body_from_file

But environment variable not found error popped up instead:

I tried to look whether the doc said much about environment variables but nothing to evaluate.

However Looking into I can find the call to crate::util::get_test_resource_file_path() when path.is_absolute is false:

Problem is this env may not be visible to cargo sub-commands as I found the hard way with tarpaulin:

  • Works okay with cargo test but tarpaulin sub-command seems to omit that environment variable.
  • Omitting the env seems to be the case with cargo sub-command.
  • Cargo documentation only lists one env passed down without explicitly ruling out others.

Doc wise Mock::return_body_from_file says explicitly either relative/absolute:

As for relative path definition, I would expect this to be the OsStr<> from the Current working directory (CWD) which may be set to be elsewhere than the directory holding the cargo manifest.

For backwards compatibility the document probably should say that the environment variable is used for relative path or behavior could be changed some way to rely on CWD that would break things relying on it to be the manifest path

Plus CWD typically is not UTF-8 guaranteed path if Into is relied (not absolutely sure whether CARGO_MANIFEST_DIR is guaranteed to be either for lossless conversion Into either if it's allowed to be non UTF-8 :1234: ?)

I personally use this pattern and document the var_os OssStr returning environment variable use for my app:

If I feel I need to enforce UTF-8 paths like Rust ecosystem like cargo does I use camino Utf8Path to see if I can upgrade from Path and match appropriate error.

Happy to submit a PR to fix doc and automatically check the truth whatever is decided when/if there is a decision what to do with this.

Code Blocks Involved

Then::body_from_file(httpmock/0.5.8/source/src/lib.rs)

Mock::return_body_from_file(httpmock/0.5.8/source/src/api/mock.rs):around 1317

Dilemma

  • Documentation advertises/promises both the relative and absolute path use
  • Relative path is implicitly derived from documentation as current working directory (CWD)
  • If relative path is used CARGO_MANIFEST_DIR is used as base path which may or may not be lossless Into
  • Cargo may or may not pass this env down to sub-command
  • std::String is always UTF-8
  • std::ffi::OsString implements Into String type but is lossy and breaks relative path guarantee
  • OsString and Path is supposed to work everywhere safely abstracting it
  • Environmental variable etc. can be non-UTF8 and requires appropriate handling boilerplate before it hits Then::body_from_file
  • Lossy conversion is due to POSIX filenames allowing anything except \0
  • Requires conversion to String for the whole path (if I read the code right:ok_woman:)
  • String/std::path::Path conversion has been always a pain
  • Many OS allows wide array of bytes in OsStr

Solution 1: Allow From &std::path::Path without using CARGO env

Pros:

  • Straightforward pattern is to pass std::path::Path directly e.g. with config::from
  • Allows relative path handling at ease over "somebody else handles it" abstraction
  • Library already uses std::Path internally despite Into String
  • Library using this can handle easily cross-platform TEST_DATA path which may contain "" or "/" path separators etc.
  • The world is not perfect problem is easier - less friction to use the library esp re: relative path
  • Documentation is the source of truth, though implicit Type impl loses (String is only UTF-8)
  • Doesn't rely on cargo env

Cons:

  • Rust configured paths are UTF-8
  • Lossy Display/Debug
  • Either confusing implementation if String is still allowed
  • Libs using may/will break if on same method - needs new method
  • Current working directory derived from var_os needs to be used instead of CARGO env

Example is using config::File::from

Where I can easily construct and pass the full Path natively and use relative path if I want

Solution 2: Enforce and be explicit about UTF-8 and handle Error thru camino

Pros:

  • Proper taint check and error
  • Lossless Display/Debug
  • Less friction for anyone who uses the library as it's checked for validity
  • Does not need new method as it was always UTF-8
  • Document implicit Type impl wins to some degree (String is only UTF-8 and we are just enforcing that)

Cons:

  • Relative path use is a pattern sadly good or bad.
  • Friction for anyone who uses the library
  • Library using this have to handle cross platform paths for TEST_DATA path which may contain "" or "/" path separators etc.
  • Adds camino crate that handles sanity on Utf8Paths
  • Documentation which advertised flexibility between relative/absolute loses

Solution 3: New fn pass by Buffer/Stream/Channel oneshot etc.

Pros:

  • Many async libs just wait-read the whole buffer internally and then process/pass the whole of it
  • Would allow timing and replaying a server behaviour in timeline basis for writing into kernel buffer out
  • Implementation could say replay sequence from libpcap file the near timing packets were either sent/recvd
  • Could differentiate between Content-Length, gzip stream, chunked modes
  • WebSocket etc. streaming
  • Can serve as building block for HTTP/2 or gRPC/Protobuffers
  • More fun than simple singular delay :)

Cons:

  • Library using this have to handle cross platform paths for TEST_DATA path which may contain "" or "/" path separators etc.
  • Library was never intended for buffer/stream handling?
  • Complexity

Solution 4: Status quo

Pros:

  • Supposed to have less burden for library

Cons:

  • Friction to use the library
  • Library using this have to handle cross platform paths for TEST_DATA path which may contain "" or "/" path separators etc.
  • Misleading error (library is not using environment variable, the full path is passed to it)
  • Still using lossy Display/Debug as it is using Path internally

Solution is probably somekind combination?

I usually do both integration / units along my /// docs or even on README.md that gets included in test run and tarpaulin --run-types DocTests takes those into account

I will check with tarpaulin too to expose the environment var but it would be nice to get some clarity as it caused a bit confusion initially for me and not sure if there is anyone doing things without cargo env :)

  • pinkforest(she/her/hers)
ducaale

ducaale

enhancement
5

I would like to assert that my HTTP request body is empty or that a certain header doesn't exist. Is this something that httpmock supports at the moment?

Currently, I can see there the following functions exist:

  • header_exists()
  • query_params_exists()
  • cookie_exists()

It would be nice if an opposite version of them existed plus one for checking if the body is empty.

Versions

Find the latest versions by id

v0.6.6 - Jan 11, 2022

v0.6.5 - Dec 22, 2021

v0.6.4 - Nov 15, 2021

Fixed minimum Rust version in README (raised from 1.47 to 1.54, see release 0.6.3 for more information).

v0.6.3 - Nov 15, 2021

  • This is a maintenance release that updates all dependencies to the most recent version.
  • Bumped minimum Rust version to 1.54 due to transitive dependency.

v0.6.2 - Aug 13, 2021

A bug was fixed that has unexported the When and Then structures. Both types are now exported again. Please refer to https://github.com/alexliesenfeld/httpmock/issues/47 for more info.

v0.6.1 - Aug 11, 2021

This is a maintenance release that updates all dependencies to the most recent version.

v0.6.0 - Aug 11, 2021

General

  • Old Mock structure based API was deprecated starting from version 0.5.0 and was removed with this version. Please switch to the new API based on the When / Then structures.
  • The two methods MockRef::times_called and MockRef::times_called_async were deprecated since version 0.5.0 and have now been removed.
  • A prelude module was added to shorten imports that are usually required when using httpmock in tests.
  • The struct MockRef has been renamed to Mock.
  • Trait MockRefExt has been renamed to MockExt.
  • Added support for x-www-form-urlencoded request bodies.

Standalone Mock Server

  • Standalone server now has a request history limit that can be adjusted.
  • All standalone servers parameters now have an environment variable fallback.
  • Standalone servers exposed and disable_access_log parameters were changed, so that they now require a value in addition to the flag itself (this is due to a limitation of structopt/clap): Before: httpmock --expose, Now: httpmock --expose true.

v0.5.8 - Apr 18, 2021

A bug has been fixed that prevented to use the mock server for requests containing a multipart/form-data request body with binary data.

v0.5.7 - Mar 29, 2021

  • Added static mock support based on YAML files for standalone mode.
  • Dockerfile Rust version has been fixed.
  • Bumped minimum Rust version to 1.46 due to transitive dependency.
  • Documentation on query parameters has been enhanced.

v0.5.6 - Mar 12, 2021

  • A bug has been fixed that caused false positive warnings in the log output.
  • Updated all dependencies to the most recent versions.
  • Assertion error messages (MockRef::assert and MockRef::assert_hits) now contain more details.

v0.5.5 - Jan 28, 2021

A bug has been fixed that prevented to use a request body in DELETE requests.

v0.5.4 - Jan 15, 2021

A new extension trait MockRefExt was added that extends the MockRef structure with additional but usually not required functionality.

v0.5.3 - Jan 07, 2021

  • This is a maintenance release that updates all dependencies to the most recent version.
  • This release bumps the minimal Rust version from 1.43+ to 1.45+.

v0.5.2 - Oct 25, 2020

  • Updated dependencies to newest version.
  • Removed dependency version fixation from v0.5.1.
  • Mock::return_body_from_file and Then::body_from_file now accept absolute and relative file paths.

v0.5.1 - Oct 24, 2020

  • Updated dependency version of futures-util to fix compile errors
  • Fixed all dependency version numbers to avoid future problems with new dependency version releases.

v0.5.0 - Oct 12, 2020

  • Breaking Change: Function Mock::expect_json_body was renamed to expect_json_body_obj.
  • Breaking Change: Function Mock::return_json_body was renamed to return_json_body_obj.
  • 🚀 Attention: A new API for mock definition was added. The old API is still available and functional, but is deprecated from now on. Please consider switching to the new API.
  • 🚀 Attention: The following new assertion functions have been added that will provide you smart and helpful error output to support debugging:
    • MockRef::assert
    • MockRef::assert_hits
    • MockRef::assert_async
    • MockRef::assert_hits_async
  • The two methods MockRef::times_called and MockRef::times_called_async are now deprecated. Consider using MockRef::hits and MockRef::hits_async.
  • The two methods Mock::return_body and Then::body now accept binary content.
  • The following new methods accept a serde_json::Value:
    • Mock::expect_json_body
    • Mock::return_json_body
    • When::json_body
    • Then::json_body
  • 🔥 Improved documentation (a lot!).
  • 👏 Debug log output is now pretty printed!
  • 🍪 Cookie matching support.
  • Support for convenient temporary and permanent redirect.
  • The log level of some log messages was changed from debug to trace to make debugging easier.

v0.5.0-beta.1 - Oct 09, 2020

v0.4.5 - Sep 18, 2020

v0.4.4 - Sep 18, 2020

v0.4.3 - Sep 02, 2020

v0.4.2 - Jul 09, 2020

v0.4.1 - Jul 09, 2020

v0.4.0 - Jul 03, 2020

v0.3.5 - Jul 01, 2020

Information - Updated Jun 22, 2022

Stars: 289
Forks: 23
Issues: 5

Rust bindings for libinjection

Add libinjection to dependencies of Cargo

Rust bindings for libinjection

Rust bindings for the C++ api of PyTorch

LIghtweight wrapper for pytorch eg libtorch in rust

Rust bindings for the C++ api of PyTorch

Rust leveldb bindings

Almost-complete bindings for leveldb for Rust

Rust leveldb bindings

rust-analyzer is a modular compiler frontend for the Rust language

It also contains some tips &amp; tricks to help you be more productive when using rust-analyzer

rust-analyzer is a modular compiler frontend for the Rust language

Rust-Lightning is a Bitcoin Lightning library written in Rust

lightning, does not handle networking, persistence, or any other I/O

Rust-Lightning is a Bitcoin Lightning library written in Rust

Rust FUSE - Filesystem in Userspace

Rust library crate for easy implementation of Crate documentation

Rust FUSE - Filesystem in Userspace

Rust crate to implement a counterpart to the PBRT book's (3rd edition) C++ code:

Some images of the test scenes are shown below, but you can find more

Rust crate to implement a counterpart to the PBRT book's (3rd edition) C++ code:

A powerful mock object library for Rust

Mock objects are a powerful technique for unit testing software

A powerful mock object library for Rust
Http

375

HTTP mocking for Rust!

Before upgrading, make sure to check out the rustfmt as a general code style

HTTP mocking for Rust!
Http

329

HTTP mocking to test Rust applications

wiremock provides HTTP mocking to perform black-box testing of Rust applications that

HTTP mocking to test Rust applications
Facebook Instagram Twitter GitHub Dribbble
Privacy