Skip to content

EratoLab/mocktail

 
 

Repository files navigation

default-monochrome

mocktail is a minimal crate for mocking HTTP and gRPC servers in Rust, with native support for streaming.

Crates.io Documentation Book Crates.io

Table of contents

Features

  • Mocks HTTP and gRPC servers
  • Mocks defined in Rust using a simple, ergonomic API
  • Provides first-class support for streaming
  • Supports delayed streaming responses to simulate slow networks or rate-limited APIs
  • Supports gRPC unary, client-streaming, server-streaming, and bidirectional-streaming methods
  • Match requests to mock responses using built-in matchers or custom matchers
  • Fully asynchronous

Getting Started

  1. Add mocktail to Cargo.toml as a development dependency:

    [dev-dependencies]
    mocktail = "0.3.0"
  2. Basic usage example:

    use mocktail::prelude::*;
    
    #[tokio::test]
    async fn test_example() -> Result<(), Box<dyn std::error::Error>> {
        // Create a mock set
        let mut mocks = MockSet::new();
    
        // Build a mock that returns a "hello world!" response
        // to POST requests to the /hello endpoint with the text "world"
        // in the body.
        mocks.mock(|when, then| {
            when.post().path("/hello").text("world");
            then.text("hello world!");
        });
    
        // Create and start a mock server
        let mut server = MockServer::new_http("example").with_mocks(mocks);
        server.start().await?;
    
        // Create a client
        let client = reqwest::Client::builder().http2_prior_knowledge().build()?;
    
        // Send a request that matches the mock created above
        let response = client
            .post(server.url("/hello"))
            .body("world")
            .send()
            .await?;
        assert_eq!(response.status(), http::StatusCode::OK);
        let body = response.text().await?;
        assert_eq!(body, "hello world!");
    
        // Send a request that doesn't match a mock
        let response = client.get(server.url("/nope")).send().await?;
        assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
    
        // Mocks can also be registered to the server directly
        // Register a mock that will match the request above that returned 404
        server.mock(|when, then| {
            when.get().path("/nope");
            then.text("yep!");
        });
    
        // Send the request again, it should now match
        let response = client.get(server.url("/nope")).send().await?;
        assert_eq!(response.status(), http::StatusCode::OK);
        let body = response.text().await?;
        assert_eq!(body, "yep!");
    
        // Mocks can be cleared from the server, enabling server reuse
        server.mocks.clear();
    
        Ok(())
    }
  3. See the book and examples in the mocktail-tests crate.

Examples

Delayed Streaming

You can simulate slow networks or rate-limited APIs by adding delays between response chunks:

use mocktail::prelude::*;
use std::time::Duration;

#[tokio::test]
async fn test_delayed_streaming() -> Result<(), Box<dyn std::error::Error>> {
    let mut mocks = MockSet::new();
    
    // Create a mock with delays between chunks
    mocks.mock(|when, then| {
        when.get().path("/slow-api");
        then.bytes_stream_with_delays([
            BodyAction::Bytes("chunk1\n".into()),
            BodyAction::Delay(Duration::from_millis(100)),
            BodyAction::Bytes("chunk2\n".into()),
            BodyAction::Delay(Duration::from_millis(100)),
            BodyAction::Bytes("chunk3\n".into()),
        ]);
    });
    
    let server = MockServer::new_http("test").with_mocks(mocks);
    server.start().await?;
    
    // The response will stream chunks with the specified delays
    let response = reqwest::get(server.url("/slow-api")).await?;
    // ... process streamed response
    
    Ok(())
}

More Examples

See examples in the mocktail-tests crate.

Related projects

This crate takes inspiration from other great mocking libraries including:

About

HTTP & gRPC server mocking for Rust, with native support for streaming

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Rust 100.0%