1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![allow(clippy::needless_doctest_main)]
//! `wiremock` provides HTTP mocking to perform black-box testing of Rust applications that
//! interact with third-party APIs.
//!
//! It provides mocking of HTTP responses using request matching and response templating.
//!
//! # Table of Contents
//! 1. [Getting started](#getting-started)
//! 2. [Matchers](#matchers)
//! 3. [Test isolation](#test-isolation)
//! 4. [Runtime compatibility](#runtime-compatibility)
//! 5. [Prior art](#prior-art)
//! 6. [Future evolution](#future-evolution)
//!
//! ## Getting started
//! ```rust
//! use wiremock::{MockServer, Mock, ResponseTemplate};
//! use wiremock::matchers::{method, path};
//!
//! #[async_std::main]
//! async fn main() {
//!     // Start a background HTTP server on a random local port
//!     let mock_server = MockServer::start().await;
//!
//!     // Arrange the behaviour of the MockServer adding a Mock:
//!     // when it receives a GET request on '/hello' it will respond with a 200.
//!     Mock::given(method("GET"))
//!         .and(path("/hello"))
//!         .respond_with(ResponseTemplate::new(200))
//!         // Mounting the mock on the mock server - it's now effective!
//!         .mount(&mock_server)
//!         .await;
//!     
//!     // If we probe the MockServer using any HTTP client it behaves as expected.
//!     let status = surf::get(format!("{}/hello", &mock_server.uri()))
//!         .await
//!         .unwrap()
//!         .status();
//!     assert_eq!(status.as_u16(), 200);
//!
//!     // If the request doesn't match any `Mock` mounted on our `MockServer` a 404 is returned.
//!     let status = surf::get(format!("{}/missing", &mock_server.uri()))
//!         .await
//!         .unwrap()
//!         .status();
//!     assert_eq!(status.as_u16(), 404);
//! }
//! ```
//!
//! ## Matchers
//!
//! `wiremock` provides a set of matching strategies out of the box - check the [`matchers`] module
//! for a complete list.
//!
//! You can define your own matchers using the [`Match`] trait, as well as using `Fn` closures.  
//! Check [`Match`]'s documentation for more details and examples.
//!
//! ## Test isolation
//!
//! Each instance of [`MockServer`] is fully isolated: [`start`] takes care of finding a random port
//! available on your local machine which is assigned to the new [`MockServer`].
//!
//! You should use one instance of [`MockServer`] for each test, to ensure full isolation and
//! no cross-test interference.
//!
//! When a [`MockServer`] instance goes out of scope (e.g. the test finishes), the corresponding
//! HTTP server running in the background is shut down to free up the port it was using.
//!
//! ## Runtime compatibility
//!
//! `wiremock` can be used (and it is tested to work) with both [`async_std`] and [`tokio`] as
//! futures runtimes.  
//! If you encounter any compatibility bug, please open an issue on our [GitHub repository].
//!
//! ## Prior art
//!
//! [`mockito`] and [`httpmock`] provide HTTP mocking for Rust.
//!
//! Check the table below to see how `wiremock` compares to them across the following dimensions:
//! - Test execution strategy (do tests have to be executed sequentially or can they be executed in parallel?);
//! - How many APIs can I mock in a test?
//! - Out-of-the-box request matchers;
//! - Extensible request matching (i.e. you can define your own matchers);
//! - Sync/Async API;
//! - Spying (e.g. verify that a mock has/hasn't been called in a test);
//! - Standalone mode (i.e. can I launch an HTTP mock server outside of a test suite?).
//!
//! |           | Test execution strategy | How many APIs can I mock? | Out-of-the-box request matchers | Extensible request maching | API   | Spying | Standalone mode |
//! |-----------|-------------------------|---------------------------|---------------------------------|----------------------------|-------|----------|-----------------|
//! | mockito   | ❌ Sequential             | ❌ 1                        | ✔                           | ❌                        | Sync  | ✔     | ❌              |
//! | httpmock | ❌ Sequential             | ❌ 1                        | ✔                           | ❌                        | Sync  | ✔     | ✔              |
//! | wiremock  | ✔ Parallel ️              | ✔ Unbounded                | ✔                           | ✔                       | Async | ❌      | ❌              |
//!
//!
//! ## Future evolution
//!
//! Spying is in scope for future releases of `wiremock`.  
//! More request matchers can be added to those provided out-of-the-box to handle common usecases.
//!
//! [`MockServer`]: struct.MockServer.html
//! [`Match`]: trait.Match.html
//! [`start`]: struct.MockServer.html#method.start
//! [`matchers`]: matchers/index.html
//! [GitHub repository]: https://github.com/LukeMathWalker/wiremock-rs
//! [`mockito`]: https://docs.rs/mockito/
//! [`httpmock`]: https://docs.rs/httpmock/
//! [`async_std`]: https://docs.rs/async-std/
//! [`tokio`]: https://docs.rs/tokio/
pub mod matchers;
mod mock;
mod mock_actor;
mod mock_server;
mod request;
mod response_template;
mod server_actor;

pub use mock::{Match, Mock, MockBuilder};
pub use mock_server::MockServer;
pub use request::Request;
pub use response_template::ResponseTemplate;