Macro mockers::mock_clone [] [src]

macro_rules! mock_clone {
    ($mock_name:ident) => { ... };
    ($mock_name:ident, share_expectations) => { ... };
}

Implements Clone for mock object.

Sometimes it is needed for mock to be clonable. Say you have following trait and function accepting this trait you need to test:

This example is not tested
#[derive(Mock)]
pub trait A {
    fn foo(&self, a: u32);
}

fn target<AC: A + Clone>(a: AC) {
    let clone = a.clone();
    clone.foo(2);
}

There are two forms of macro invokation. First one with mock struct name as single argument mocks clone method, so you may specify arbitrary expectations and reactions on it:

This example is not tested
mock_clone!(AMock);

#[test]
fn test_clone_mock() {
    let scenario = Scenario::new();
    let mock = scenario.create_mock_for::<A>();
    let mock_clone = scenario.create_mock_for::<A>();

    scenario.expect(mock_clone.foo_call(2).and_return_default().times(1));
    scenario.expect(mock.clone_call().and_return(mock_clone));

    target(mock);
}

Please note that you must specify mock name, not name of mocked trait. This is limitation of current macro_rules system. If you mocked trait using derive attribute, then just append "Mock" to trait name.

Second form accepts one additional parameter - strategy, which specifies how cloned mock should behave. Currently there is only one strategy - "share_expectations", which means that all mock clones are indistinguishable and expectations set on one of them may be satisfied by calls made on another one. This is very useful when mocked trait behaves like handle to some real implementation.

This example is not tested
mock_clone!(AMock, share_expectations);

#[test]
fn test_shared() {
    let scenario = Scenario::new();
    let mock = scenario.create_mock_for::<A>();

    scenario.expect(mock.foo_call(2).and_return_default().times(1));

    target(mock);
}