pub struct MockLayerBuilder { /* private fields */ }
Expand description
Implementations§
Source§impl MockLayerBuilder
impl MockLayerBuilder
Sourcepub fn named(self, name: impl Display) -> Self
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
Sourcepub fn event(self, event: ExpectedEvent) -> Self
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();
Sourcepub fn new_span<I>(self, new_span: I) -> Self
pub fn new_span<I>(self, new_span: I) -> Self
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();
Sourcepub fn enter<S>(self, span: S) -> Selfwhere
S: Into<ExpectedSpan>,
pub fn enter<S>(self, span: S) -> Selfwhere
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();
Sourcepub fn exit<S>(self, span: S) -> Selfwhere
S: Into<ExpectedSpan>,
pub fn exit<S>(self, span: S) -> Selfwhere
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();
Sourcepub fn only(self) -> Self
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();
Sourcepub fn run(self) -> MockLayer
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);
Sourcepub fn run_with_handle(self) -> (MockLayer, MockHandle)
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();