1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
/// 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: /// /// ```rust,ignore /// #[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: /// /// ```rust,ignore /// 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. /// /// ```rust,ignore /// 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); /// } /// ``` #[macro_export] macro_rules! mock_clone { ($mock_name:ident) => { #[cfg(test)] impl Clone for $mock_name { fn clone(&self) -> Self { let method_data = ::mockers::MethodData{mock_id: self.mock_id, mock_type_id: 0usize, method_name: "clone",}; let action = self.scenario.borrow_mut().verify0(method_data); action.call() } } impl $mock_name { #[allow(dead_code)] pub fn clone_call(&self) -> ::mockers::CallMatch0<Self> { ::mockers::CallMatch0::new(self.mock_id, 0usize, "clone") } } }; ($mock_name:ident, share_expectations) => { #[cfg(test)] impl Clone for $mock_name { fn clone(&self) -> Self { use $crate::Mock; $mock_name::new(self.mock_id, self.scenario.clone()) } } }; }