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

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

Struct tracing_mock::subscriber::MockSubscriberBuilder

source ·
pub struct MockSubscriberBuilder { /* private fields */ }
Expand description

A builder for constructing MockSubscribers.

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

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

Implementations§

source§

impl MockSubscriberBuilder

source

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

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

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

By default, the mock subscriber’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 subscriber, this is sufficient. However, some tests may include multiple subscribers, in order to test interactions between multiple subscribers. In that case, it can be helpful to give each subscriber a separate name to distinguish where the debugging output comes from.

§Examples

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

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

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

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

let _collect = tracing_subscriber::registry()
    .with(
        subscriber_2.with_filter(tracing_subscriber::filter::filter_fn(move |_meta| true))
    )
    .set_default();
{
    let _collect = tracing_subscriber::registry()
        .with(
            subscriber_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 subscriber which didn’t received the event was the one named subscriber-2, which is correct as the subscriber named subscriber-1 was the default when the event was recorded:

[main::subscriber-2] more notifications expected: [
    Event(
        MockEvent,
    ),
]', tracing-mock/src/collector.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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 parent.

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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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(self, span: ExpectedSpan) -> Self

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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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(self, span: ExpectedSpan) -> Self

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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

let _collect = tracing_subscriber::registry()
    .with(subscriber.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) -> MockSubscriber

Consume this builder and return a MockSubscriber 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::Collect;
use tracing_mock::subscriber;
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

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

assert_eq!(collector.max_level_hint(), None);
source

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

Consume this builder and return a MockSubscriber 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, subscriber};
use tracing_subscriber::{subscribe::CollectExt, util::SubscriberInitExt, Subscribe};

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

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

tracing::info!("event");

handle.assert_finished();

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>,

§

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>,

§

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> WithCollector for T

source§

fn with_collector<C>(self, collector: C) -> WithDispatch<Self>
where C: Into<Dispatch>,

Attaches the provided collector to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_collector(self) -> WithDispatch<Self>

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