wiremock/
lib.rs

1#![allow(clippy::needless_doctest_main)]
2//! `wiremock` provides HTTP mocking to perform black-box testing of Rust applications that
3//! interact with third-party APIs.
4//!
5//! It provides mocking of HTTP responses using request matching and response templating.
6//!
7//! ## How to install
8//!
9//! Add `wiremock` to your development dependencies:
10//! ```toml
11//! [dev-dependencies]
12//! # ...
13//! wiremock = "0.5"
14//! ```
15//! If you are using [`cargo-edit`](https://github.com/killercup/cargo-edit), run
16//! ```bash
17//! cargo add wiremock --dev
18//! ```
19//!
20//! ## Getting started
21//!
22//! ```rust
23//! use wiremock::{MockServer, Mock, ResponseTemplate};
24//! use wiremock::matchers::{method, path};
25//!
26//! #[async_std::main]
27//! async fn main() {
28//!     // Start a background HTTP server on a random local port
29//!     let mock_server = MockServer::start().await;
30//!
31//!     // Arrange the behaviour of the MockServer adding a Mock:
32//!     // when it receives a GET request on '/hello' it will respond with a 200.
33//!     Mock::given(method("GET"))
34//!         .and(path("/hello"))
35//!         .respond_with(ResponseTemplate::new(200))
36//!         // Mounting the mock on the mock server - it's now effective!
37//!         .mount(&mock_server)
38//!         .await;
39//!     
40//!     // If we probe the MockServer using any HTTP client it behaves as expected.
41//!     let status = reqwest::get(format!("{}/hello", &mock_server.uri()))
42//!         .await
43//!         .unwrap()
44//!         .status();
45//!     assert_eq!(status, 200);
46//!
47//!     // If the request doesn't match any `Mock` mounted on our `MockServer` a 404 is returned.
48//!     let status = reqwest::get(format!("{}/missing", &mock_server.uri()))
49//!         .await
50//!         .unwrap()
51//!         .status();
52//!     assert_eq!(status, 404);
53//! }
54//! ```
55//!
56//! ## Matchers
57//!
58//! `wiremock` provides a set of matching strategies out of the box - check the [`matchers`] module
59//! for a complete list.
60//!
61//! You can define your own matchers using the [`Match`] trait, as well as using `Fn` closures.  
62//! Check [`Match`]'s documentation for more details and examples.
63//!
64//! ## Spying
65//!
66//! `wiremock` empowers you to set expectations on the number of invocations to your [`Mock`]s -
67//! check the [`expect`] method for more details.
68//!
69//! Expectations can be used to verify that a side-effect has (or has not) taken place!
70//!
71//! Expectations are automatically verified during the shutdown of each [`MockServer`] instance,
72//! at the end of your test. A failed verification will trigger a panic.  
73//! By default, no expectations are set on your [`Mock`]s.
74//!
75//! ## Responses
76//!
77//! `wiremock` lets you specify pre-determined responses using [`ResponseTemplate`] and
78//! [`respond_with`].
79//!
80//! You also given the option to have [`Mock`]s that return different responses based on the matched
81//! [`Request`] using the [`Respond`] trait.  
82//! Check [`Respond`]'s documentation for more details and examples.
83//!
84//! ## Test isolation
85//!
86//! Each instance of [`MockServer`] is fully isolated: [`start`] takes care of finding a random port
87//! available on your local machine which is assigned to the new [`MockServer`].
88//!
89//! To ensure full isolation and no cross-test interference, [`MockServer`]s shouldn't be
90//! shared between tests. Instead, [`MockServer`]s should be created in the test where they are used.
91//!
92//! When a [`MockServer`] instance goes out of scope (e.g. the test finishes), the corresponding
93//! HTTP server running in the background is shut down to free up the port it was using.
94//!
95//! ## Runtime compatibility
96//!
97//! `wiremock` can be used (and it is tested to work) with both [`async_std`] and [`tokio`] as
98//! futures runtimes.  
99//! If you encounter any compatibility bug, please open an issue on our [GitHub repository].
100//!
101//! ## Efficiency
102//!
103//! `wiremock` maintains a pool of mock servers in the background to minimise the number of
104//! connections and the time spent starting up a new [`MockServer`].  
105//! Pooling reduces the likelihood of you having to tune your OS configurations (e.g. ulimit).
106//!
107//! The pool is designed to be invisible: it makes your life easier and your tests faster. If you
108//! end up having to worry about it, it's a bug: open an issue!
109//!
110//! ## Prior art
111//!
112//! [`mockito`] and [`httpmock`] provide HTTP mocking for Rust.
113//!
114//! Check the table below to see how `wiremock` compares to them across the following dimensions:
115//! - Test execution strategy (do tests have to be executed sequentially or can they be executed in parallel?);
116//! - How many APIs can I mock in a test?
117//! - Out-of-the-box request matchers;
118//! - Extensible request matching (i.e. you can define your own matchers);
119//! - Sync/Async API;
120//! - Spying (e.g. verify that a mock has/hasn't been called in a test);
121//! - Standalone mode (i.e. can I launch an HTTP mock server outside of a test suite?).
122//!
123//! |           | Test execution strategy | How many APIs can I mock? | Out-of-the-box request matchers | Extensible request matching | API   | Spying | Standalone mode |
124//! |-----------|-------------------------|---------------------------|---------------------------------|----------------------------|-------|----------|-----------------|
125//! | mockito   | ❌ Sequential           | ❌ 1                        | ✔                           | ❌                        | Sync  | ✔     | ❌              |
126//! | httpmock  | ✔ Parallel              | ✔ Unbounded                | ✔                           | ✔                        | Async/Sync  | ✔     | ✔              |
127//! | wiremock  | ✔ Parallel ️             | ✔ Unbounded                | ✔                           | ✔                       | Async | ✔      | ❌              |
128//!
129//!
130//! ## Future evolution
131//!
132//! More request matchers can be added to those provided out-of-the-box to handle common usecases.
133//!
134//! ## Related projects
135//!
136//! * [`stubr`](https://github.com/beltram/stubr) for mounting [`Wiremock`](http://wiremock.org/) json stubs in a [`MockServer`]. Also works as a cli.
137//!
138//! [`MockServer`]: MockServer
139//! [`start`]: MockServer::start
140//! [`expect`]: Mock::expect
141//! [`respond_with`]: MockBuilder::respond_with
142//! [GitHub repository]: https://github.com/LukeMathWalker/wiremock-rs
143//! [`mockito`]: https://docs.rs/mockito/
144//! [`httpmock`]: https://docs.rs/httpmock/
145//! [`async_std`]: https://docs.rs/async-std/
146//! [`tokio`]: https://docs.rs/tokio/
147pub mod http;
148pub mod matchers;
149mod mock;
150mod mock_server;
151mod mock_set;
152mod mounted_mock;
153mod request;
154mod respond;
155mod response_template;
156mod verification;
157
158pub type ErrorResponse = Box<dyn std::error::Error + Send + Sync + 'static>;
159
160pub use mock::{Match, Mock, MockBuilder, Times};
161pub use mock_server::{MockGuard, MockServer, MockServerBuilder};
162pub use request::{BodyPrintLimit, Request};
163pub use respond::Respond;
164pub use response_template::ResponseTemplate;