Struct mimicry::MockRef

source ·
pub struct MockRef<T: Mock> { /* private fields */ }
Expand description

Reference to a mock state used when mocking async functions / methods.

A separate reference type is required because it would be unsound to spill a direct state reference or a reference to Mut across await boundaries. (Internally, such a reference is produced using interior mutability primitives like RefCell.) Instead, MockRef provides access to the state using with() or with_mut() methods that do not overly restrict the lifetime of the state reference.

Examples

Mock with immutable state

#[mock(using = "CountingMock")]
async fn answer() -> u32 { 42 }

#[derive(Default, Mock)]
struct CountingMock(AtomicU32);

impl CheckRealCall for CountingMock {}

impl CountingMock {
    async fn answer(r: MockRef<Self>) -> u32 {
        r.with(|this| this.0.fetch_add(1, Ordering::Relaxed))
    }
}

Mock with mutable state

Also demonstrates spying logic.

#[mock(using = "CountingMock")]
async fn answer() -> u32 { 42 }

#[derive(Default, Mock)]
#[mock(mut)]
struct CountingMock {
    captured_value: Option<u32>,
}

impl CountingMock {
    #[async_recursion] // workaround for `async fn` recursion
    async fn answer(r: MockRef<Self>) -> u32 {
        let captured = r.with_mut(|this| this.captured_value);
        if let Some(captured) = captured {
            captured
        } else {
            let value = r.call_real().async_scope(answer()).await;
            r.with_mut(|this| this.captured_value = Some(value));
            value
        }
    }
}

let guard = CountingMock::default().set_as_mock();
assert_eq!(answer().await, 42);
let captured = guard.into_inner().captured_value;
assert_eq!(captured, Some(42));

Implementations

Accesses the underlying mock state.

Panics

Panics if the mock state has gone missing. This is a sign that test code is ill-constructed (e.g., the mock is removed before all mocked calls are made).

Accesses the underlying Mutable mock state.

Panics

Panics if the mock state has gone missing. This is a sign that test code is ill-constructed (e.g., the mock is removed before all mocked calls are made).

Trait Implementations

Delegates all calls to the mocked functions / methods to the real implementation until the returned RealCallGuard is dropped. Read more
Delegates the first call to the mocked functions / methods to the real implementation until the returned RealCallGuard is dropped. Further calls will be directed to the mock. Read more
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.