tracing_mock::layer

Struct MockLayerBuilder

Source
pub struct MockLayerBuilder { /* private fields */ }
Expand description

A builder for constructing MockLayers.

The methods on this builder set expectations which are then validated by the constructed MockLayer.

For a detailed description and examples see the documentation for the methods and the layer module.

Implementations§

Source§

impl MockLayerBuilder

Source

pub fn named(self, name: impl Display) -> Self

Overrides the name printed by the mock layer’s debugging output.

The debugging output is displayed if the test panics, or if the test is run with --nocapture.

By default, the mock layer’s name is the name of the test (technically, the name of the thread where it was created, which is the name of the test unless tests are run with --test-threads=1). When a test has only one mock layer, this is sufficient. However, some tests may include multiple layers, in order to test interactions between multiple layers. In that case, it can be helpful to give each layers a separate name to distinguish where the debugging output comes from.

§Examples

In the following example, we create two layers, both expecting to receive an event. As we only record a single event, the test will fail:

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

let (layer_1, handle_1) = layer::mock()
    .named("layer-1")
    .event(expect::event())
    .run_with_handle();

let (layer_2, handle_2) = layer::mock()
    .named("layer-2")
    .event(expect::event())
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(
        layer_2.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true))
    )
    .set_default();
{
    let _subscriber =  tracing_subscriber::registry()
        .with(
            layer_1
                .with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true))
        )
        .set_default();

    tracing::info!("a");
}

handle_1.assert_finished();
handle_2.assert_finished();

In the test output, we see that the layer which didn’t received the event was the one named layer-2, which is correct as the layer named layer-1 was the default when the event was recorded:

[main::layer-2] more notifications expected: [
    Event(
        MockEvent,
    ),
]', tracing-mock/src/subscriber.rs:472:13
Source

pub fn event(self, event: ExpectedEvent) -> Self

Adds an expectation that an event matching the ExpectedEvent will be recorded next.

The event can be a default mock which will match any event (expect::event()) or can include additional expectations. See the ExpectedEvent documentation for more details.

If an event is recorded that doesn’t match the ExpectedEvent, or if something else (such as entering a span) is recorded first, then the expectation will fail.

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

let (layer, handle) = layer::mock()
    .event(expect::event())
    .run_with_handle();

let _subscriber = tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

tracing::info!("event");

handle.assert_finished();

A span is entered before the event, causing the test to fail:

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

let (layer, handle) = layer::mock()
    .event(expect::event())
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

let span = tracing::info_span!("span");
let _guard = span.enter();
tracing::info!("event");

handle.assert_finished();
Source

pub fn new_span<I>(self, new_span: I) -> Self
where I: Into<NewSpan>,

Adds an expectation that the creation of a span will be recorded next.

This function accepts Into<NewSpan> instead of ExpectedSpan directly. NewSpan can be used to test span fields and the span ancestry.

The new span doesn’t need to be entered for this expectation to succeed.

If a span is recorded that doesn’t match the ExpectedSpan, or if something else (such as an event) is recorded first, then the expectation will fail.

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing")
    .with_fields(expect::field("testing").with_value(&"yes"));
let (layer, handle) = layer::mock()
    .new_span(span)
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

_ = tracing::info_span!("the span we're testing", testing = "yes");

handle.assert_finished();

An event is recorded before the span is created, causing the test to fail:

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing")
    .with_fields(expect::field("testing").with_value(&"yes"));
let (layer, handle) = layer::mock()
    .new_span(span)
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

tracing::info!("an event");
_ = tracing::info_span!("the span we're testing", testing = "yes");

handle.assert_finished();
Source

pub fn enter<S>(self, span: S) -> Self
where S: Into<ExpectedSpan>,

Adds an expectation that entering a span matching the ExpectedSpan will be recorded next.

This expectation is generally accompanied by a call to exit, since an entered span will typically be exited. If used together with only, this is likely necessary, because the span will be dropped before the test completes (except in rare cases, such as if std::mem::forget is used).

If the span that is entered doesn’t match the ExpectedSpan, or if something else (such as an event) is recorded first, then the expectation will fail.

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing");
let (layer, handle) = layer::mock()
    .enter(&span)
    .exit(&span)
    .only()
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

{
    let span = tracing::info_span!("the span we're testing");
    let _entered = span.enter();
}

handle.assert_finished();

An event is recorded before the span is entered, causing the test to fail:

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing");
let (layer, handle) = layer::mock()
    .enter(&span)
    .exit(&span)
    .only()
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

{
    tracing::info!("an event");
    let span = tracing::info_span!("the span we're testing");
    let _entered = span.enter();
}

handle.assert_finished();
Source

pub fn exit<S>(self, span: S) -> Self
where S: Into<ExpectedSpan>,

Adds an expectation that exiting a span matching the ExpectedSpan will be recorded next.

As a span may be entered and exited multiple times, this is different from the span being closed. In general enter and exit should be paired.

If the span that is exited doesn’t match the ExpectedSpan, or if something else (such as an event) is recorded first, then the expectation will fail.

Note: Ensure that the guard returned by Span::enter is dropped before calling MockHandle::assert_finished.

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing");
let (layer, handle) = layer::mock()
    .enter(&span)
    .exit(&span)
    .only()
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();
{
    let span = tracing::info_span!("the span we're testing");
    let _entered = span.enter();
}

handle.assert_finished();

An event is recorded before the span is exited, causing the test to fail:

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

let span = expect::span()
    .at_level(tracing::Level::INFO)
    .named("the span we're testing");
let (layer, handle) = layer::mock()
    .enter(&span)
    .exit(&span)
    .only()
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

{
    let span = tracing::info_span!("the span we're testing");
    let _entered = span.enter();
    tracing::info!("an event");
}

handle.assert_finished();
Source

pub fn only(self) -> Self

Expects that no further traces are received.

The call to only should appear immediately before the final call to run or run_with_handle, as any expectations which are added after only will not be considered.

§Examples

Consider this simple test. It passes even though we only expect a single event, but receive three:

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

let (layer, handle) = layer::mock()
    .event(expect::event())
    .run_with_handle();

let _subscriber = tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

tracing::info!("a");
tracing::info!("b");
tracing::info!("c");

handle.assert_finished();

After including only, the test will fail:

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

let (layer, handle) = layer::mock()
    .event(expect::event())
    .only()
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

tracing::info!("a");
tracing::info!("b");
tracing::info!("c");

handle.assert_finished();
Source

pub fn run(self) -> MockLayer

Consume this builder and return a MockLayer which can be set as the default subscriber.

This function is similar to run_with_handle, but it doesn’t return a MockHandle. This is useful if the desired assertions can be checked externally to the subscriber.

§Examples

The following test is used within the tracing-subscriber codebase:

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

let unfiltered = layer::named("unfiltered").run().boxed();
let info = layer::named("info")
    .run()
    .with_filter(tracing_core::LevelFilter::INFO)
    .boxed();
let debug = layer::named("debug")
    .run()
    .with_filter(tracing_core::LevelFilter::DEBUG)
    .boxed();

let subscriber = tracing_subscriber::registry().with(vec![unfiltered, info, debug]);

assert_eq!(subscriber.max_level_hint(), None);
Source

pub fn run_with_handle(self) -> (MockLayer, MockHandle)

Consume this builder and return a MockLayer which can be set as the default subscriber and a MockHandle which can be used to validate the provided expectations.

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

let (layer, handle) = layer::mock()
    .event(expect::event())
    .run_with_handle();

let _subscriber =  tracing_subscriber::registry()
    .with(layer.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true)))
    .set_default();

tracing::info!("event");

handle.assert_finished();

Trait Implementations§

Source§

impl Debug for MockLayerBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more