macros_mid/
macros_mid.rs

1// Here we'll use the mid-level macros available in Simulacrum.
2//
3// There is one to create the Mock struct itself, and one to facilitate
4// marking methods as called when implementing the trait for the Mock struct.
5//
6// Note that if you want more control over your Mock object, you should look into
7// the low-level API available in the `simulacrum` crate.
8//
9// You can see that & and &mut parameters are mocked as *const and *mut. Also note
10// that the *mut parameter uses `was_called!()` with a `()` return type and
11// `.returning()` to have its return behavior specified.
12
13extern crate simulacrum;
14
15use simulacrum::*;
16
17trait CoolTrait {
18    // Shared self
19    fn foo(&self);
20
21    // Mutable self
22    fn bar(&mut self);
23
24    // One parameter and returning a value
25    fn goop(&mut self, flag: bool) -> u32;
26
27    // Multiple parameters
28    fn zing(&self, first: i32, second: bool);
29
30    // Static reference
31    fn boop(&self, name: &'static str);
32
33    // Shared reference
34    fn store(&self, val: &i64);
35
36    // Mutable reference
37    fn toggle(&self, bit: &mut bool);
38}
39
40create_mock_struct! {
41    struct CoolTraitMock: {
42        expect_foo("foo");
43        expect_bar("bar");
44        expect_goop("goop") bool => u32;
45        expect_zing("zing") (i32, bool);
46        expect_boop("boop") &'static str;
47        expect_store("store") *const i64;
48        expect_toggle("toggle") *mut bool;
49    }
50}
51
52impl CoolTrait for CoolTraitMock {
53    fn foo(&self) {
54        was_called!(self, "foo")
55    }
56
57    fn bar(&mut self) {
58        was_called!(self, "bar")
59    }
60
61    fn goop(&mut self, flag: bool) -> u32 {
62        was_called!(self, "goop", (flag: bool) -> u32)
63    }
64
65    fn zing(&self, first: i32, second: bool) {
66        was_called!(self, "zing", (first: i32, second: bool))
67    }
68
69    fn boop(&self, name: &'static str) {
70        was_called!(self, "boop", (name: &'static str))
71    }
72
73    fn store(&self, val: &i64) {
74        was_called!(self, "store", (val: *const i64))
75    }
76
77    fn toggle(&self, bit: &mut bool) {
78        was_called!(self, "toggle", (bit: *mut bool))
79    }
80}
81
82fn main() {
83    // Create a mock object
84    let mut m = CoolTraitMock::new();
85
86    // Set up expectations for it
87    m.expect_bar().called_never();
88    m.expect_foo().called_once();
89    m.then().expect_goop().called_once().with(true).returning(|_| 5);
90    m.then().expect_zing().called_once().with(params!(13, false));
91    m.expect_boop().called_times(2);
92    m.expect_store().called_once().with(deref(777));
93    m.expect_toggle().called_once().with(deref(true))
94                                   .modifying(|&mut arg| { unsafe { *arg = false } });
95
96    // Execute test code
97    m.foo();
98    assert_eq!(m.goop(true), 5);
99    m.zing(13, false);
100    m.boop("hey");
101    m.boop("yo");
102    m.store(&777);
103    let mut b = true;
104    m.toggle(&mut b);
105    assert_eq!(b, false);
106
107    // When the mock object is dropped, its expectations will be evaluated
108}