Trait mocktopus::mocking::Mockable [] [src]

pub trait Mockable<T, O> {
    unsafe fn mock_raw<M: Fn<T, Output = MockResult<T, O>>>(&self, mock: M);
fn mock_safe<M: Fn<T, Output = MockResult<T, O>> + 'static>(&self, mock: M); }

Trait for setting up mocks

The trait is implemented for all functions, so its methods can be called on any function.

Note: methods have any effect only if called on functions annotated as mockable.

Required Methods

Core function for setting up mocks

The passed closure is called whenever the mocked function is called. Depending on variant of returned MockResult the mocked function continues to run or returns immediately. In case of continuation the function arguments can be modified or replaced.

The mock closure is saved in a thread local static storage, so it has effect only in thread, where it was set. Each Rust test is executed in separate thread, so mocks do not leak between them.

Safety

It is up to the user to make sure, that the closure is valid long enough to serve all calls to mocked function. If the mock closure uses any non-static values or references, it will silently become invalid at some point of host thread lifetime.

#[mockable]
fn get_string(context: &Context) -> &String {
    context.get_string()
}

#[test]
fn get_string_test() {
    let mocked = "mocked".to_string();
    unsafe {
        get_string.mock_raw(|_| MockResult::Return(&mocked));
    }

    assert_eq!("mocked", get_string(&Context::default()));
}

A safe variant of mock_raw for static closures

The safety is guaranteed by forcing passed closure to be static. This eliminates the problem of using non-static values, which may not live long enough.

#[mockable]
fn get_string() -> String {
    "not mocked".to_string()
}

#[test]
fn get_string_test() {
    get_string.mock_safe(|| MockResult::Return("mocked".to_string()));

    assert_eq!("mocked", get_string());
}

Implementors