tracing_mock

Module layer

Source
Expand description

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

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

use tracing_mock::{expect, layer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};

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

// Use `set_default` to apply the `MockSubscriber` until the end
// of the current scope (when the guard `_subscriber` is dropped).
let _subscriber =  tracing_subscriber::registry()
    .with(layer.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, layer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};

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

// Use `set_default` to apply the `MockLayers` until the end
// of the current scope (when the guard `_subscriber` is dropped).
let _subscriber = tracing_subscriber::registry()
    .with(layer.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, layer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};  

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

// Use `set_default` to apply the `MockSubscriber` until the end
// of the current scope (when the guard `_subscriber` is dropped).
let _subscriber =  tracing_subscriber::registry()
    .with(layer.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§