🛈 Note: This is pre-release documentation for the upcoming tracing 0.2.0 ecosystem.

For the release documentation, please see docs.rs, instead.

Expand description

An implementation of the Subscribe trait which validates that the tracing data it receives matches the expected output for a test.

The MockSubscriber is the central component in these tools. The MockSubscriber has expectations set on it which are later validated as the code under test is run.

use tracing_mock::{expect, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

let (subscriber, handle) = subscriber::mock()
    // Expect a single event with a specified message
    .event(expect::event().with_fields(expect::message("droids")))
    .run_with_handle();

// Use `set_default` to apply the `MockSubscriber` until the end
// of the current scope (when the guard `_collect` is dropped).
let _collect = tracing_subscriber::registry()
    .with(subscriber.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

// These *are* the droids we are looking for
tracing::info!("droids");

// Use the handle to check the assertions. This line will panic if an
// assertion is not met.
handle.assert_finished();

A more complex example may consider multiple spans and events with their respective fields:

use tracing_mock::{expect, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

let span = expect::span()
    .named("my_span");
let (subscriber, handle) = subscriber::mock()
    // Enter a matching span
    .enter(span.clone())
    // Record an event with message "collect parting message"
    .event(expect::event().with_fields(expect::message("say hello")))
    // Exit a matching span
    .exit(span)
    // Expect no further messages to be recorded
    .only()
    // Return the collector and handle
    .run_with_handle();

// Use `set_default` to apply the `MockSubscriber` until the end
// of the current scope (when the guard `_collect` is dropped).
let _collect = tracing_subscriber::registry()
    .with(subscriber.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

{
    let span = tracing::trace_span!(
        "my_span",
        greeting = "hello world",
    );

    let _guard = span.enter();
    tracing::info!("say hello");
}

// Use the handle to check the assertions. This line will panic if an
// assertion is not met.
handle.assert_finished();

If we modify the previous example so that we don’t enter the span before recording an event, the test will fail:

use tracing_mock::{expect, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

let span = expect::span()
    .named("my_span");
let (subscriber, handle) = subscriber::mock()
    // Enter a matching span
    .enter(span.clone())
    // Record an event with message "collect parting message"
    .event(expect::event().with_fields(expect::message("say hello")))
    // Exit a matching span
    .exit(span)
    // Expect no further messages to be recorded
    .only()
    // Return the collector and handle
    .run_with_handle();

// Use `set_default` to apply the `MockSubscriber` until the end
// of the current scope (when the guard `_collect` is dropped).
let _collect = tracing_subscriber::registry()
    .with(subscriber.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

{
    let span = tracing::trace_span!(
        "my_span",
        greeting = "hello world",
    );

    // Don't enter the span.
    // let _guard = span.enter();
    tracing::info!("say hello");
}

// Use the handle to check the assertions. This line will panic if an
// assertion is not met.
handle.assert_finished();

Structs§

Functions§