1 | // vim: tw=80 |
2 | //! A powerful mock object library for Rust. |
3 | //! |
4 | //! Mockall provides tools to create mock versions of almost any trait |
5 | //! or struct. They can be used in unit tests as a stand-in for the real |
6 | //! object. |
7 | //! |
8 | //! # Usage |
9 | //! |
10 | //! There are two ways to use Mockall. The easiest is to use |
11 | //! [`#[automock]`](attr.automock.html). It can mock most traits, or structs |
12 | //! that only have a single `impl` block. For things it can't handle, there is |
13 | //! [`mock!`]. |
14 | //! |
15 | //! Whichever method is used, the basic idea is the same. |
16 | //! * Create a mock struct. It's name will be the same as the original, with |
17 | //! "Mock" prepended. |
18 | //! * In your test, instantiate the mock struct with its `new` or `default` |
19 | //! method. |
20 | //! * Set expectations on the mock struct. Each expectation can have required |
21 | //! argument matchers, a required call count, and a required position in a |
22 | //! [`Sequence`]. Each expectation must also have a return value. |
23 | //! * Supply the mock object to the code that you're testing. It will return |
24 | //! the preprogrammed return values supplied in the previous step. Any |
25 | //! accesses contrary to your expectations will cause a panic. |
26 | //! |
27 | //! # User Guide |
28 | //! |
29 | //! * [`Getting started`](#getting-started) |
30 | //! * [`Static Return values`](#static-return-values) |
31 | //! * [`Matching arguments`](#matching-arguments) |
32 | //! * [`Call counts`](#call-counts) |
33 | //! * [`Sequences`](#sequences) |
34 | //! * [`Checkpoints`](#checkpoints) |
35 | //! * [`Reference arguments`](#reference-arguments) |
36 | //! * [`Reference return values`](#reference-return-values) |
37 | //! * [`impl Trait`](#impl-trait) |
38 | //! * [`Mocking structs`](#mocking-structs) |
39 | //! * [`Generic methods`](#generic-methods) |
40 | //! * [`Methods with generic lifetimes`](#methods-with-generic-lifetimes) |
41 | //! * [`Generic traits and structs`](#generic-traits-and-structs) |
42 | //! * [`Associated types`](#associated-types) |
43 | //! * [`Multiple and inherited traits`](#multiple-and-inherited-traits) |
44 | //! * [`External traits`](#external-traits) |
45 | //! * [`Static methods`](#static-methods) |
46 | //! * [`Modules`](#modules) |
47 | //! * [`Foreign functions`](#foreign-functions) |
48 | //! * [`Debug`](#debug) |
49 | //! * [`Async Traits`](#async-traits) |
50 | //! * [`Crate features`](#crate-features) |
51 | //! * [`Examples`](#examples) |
52 | //! |
53 | //! ## Getting Started |
54 | //! ``` |
55 | //! use mockall::*; |
56 | //! use mockall::predicate::*; |
57 | //! #[automock] |
58 | //! trait MyTrait { |
59 | //! fn foo(&self, x: u32) -> u32; |
60 | //! } |
61 | //! |
62 | //! fn call_with_four(x: &MyTrait) -> u32 { |
63 | //! x.foo(4) |
64 | //! } |
65 | //! |
66 | //! let mut mock = MockMyTrait::new(); |
67 | //! mock.expect_foo() |
68 | //! .with(predicate::eq(4)) |
69 | //! .times(1) |
70 | //! .returning(|x| x + 1); |
71 | //! assert_eq!(5, call_with_four(&mock)); |
72 | //! ``` |
73 | //! |
74 | //! ## Static Return values |
75 | //! |
76 | //! Every expectation must have an associated return value (though when the |
77 | //! **nightly** feature is enabled expectations will automatically return the |
78 | //! default values of their return types, if their return types implement |
79 | //! `Default`.). For methods that return a `static` value, the macros will |
80 | //! generate an `Expectation` struct like |
81 | //! [`this`](examples::__mock_MockFoo_Foo::__foo::Expectation). |
82 | //! There are two ways to set such an expectation's return value: with a |
83 | //! constant |
84 | //! ([`return_const`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const)) |
85 | //! or a closure |
86 | //! ([`returning`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning)). |
87 | //! A closure will take the method's arguments by value. |
88 | //! |
89 | //! ``` |
90 | //! # use mockall::*; |
91 | //! #[automock] |
92 | //! trait MyTrait { |
93 | //! fn foo(&self) -> u32; |
94 | //! fn bar(&self, x: u32, y: u32) -> u32; |
95 | //! } |
96 | //! |
97 | //! let mut mock = MockMyTrait::new(); |
98 | //! mock.expect_foo() |
99 | //! .return_const(42u32); |
100 | //! mock.expect_bar() |
101 | //! .returning(|x, y| x + y); |
102 | //! ``` |
103 | //! |
104 | //! Additionally, constants that aren't `Clone` can be returned with the |
105 | //! [`return_once`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once) |
106 | //! method. |
107 | //! |
108 | //! ``` |
109 | //! # use mockall::*; |
110 | //! struct NonClone(); |
111 | //! #[automock] |
112 | //! trait Foo { |
113 | //! fn foo(&self) -> NonClone; |
114 | //! } |
115 | //! |
116 | //! # fn main() { |
117 | //! let mut mock = MockFoo::new(); |
118 | //! let r = NonClone{}; |
119 | //! mock.expect_foo() |
120 | //! .return_once(move || r); |
121 | //! # } |
122 | //! ``` |
123 | //! |
124 | //! `return_once` can also be used for computing the return value with an |
125 | //! `FnOnce` closure. This is useful for returning a non-`Clone` value and also |
126 | //! triggering side effects at the same time. |
127 | //! |
128 | //! ``` |
129 | //! # use mockall::*; |
130 | //! fn do_something() {} |
131 | //! |
132 | //! struct NonClone(); |
133 | //! |
134 | //! #[automock] |
135 | //! trait Foo { |
136 | //! fn foo(&self) -> NonClone; |
137 | //! } |
138 | //! |
139 | //! # fn main() { |
140 | //! let mut mock = MockFoo::new(); |
141 | //! let r = NonClone{}; |
142 | //! mock.expect_foo() |
143 | //! .return_once(move || { |
144 | //! do_something(); |
145 | //! r |
146 | //! }); |
147 | //! # } |
148 | //! ``` |
149 | //! |
150 | //! Mock objects are always `Send`. If you need to use a return type that |
151 | //! isn't, you can use the |
152 | //! [`return_const_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const_st), |
153 | //! [`returning_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning_st), |
154 | //! or |
155 | //! [`return_once_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once_st), |
156 | //! methods. If you need to match arguments that are not `Send`, you can use the |
157 | //! [`withf_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf_st) |
158 | //! These take a non-`Send` object and add runtime access checks. The wrapped |
159 | //! object will be `Send`, but accessing it from multiple threads will cause a |
160 | //! runtime panic. |
161 | //! |
162 | //! ``` |
163 | //! # use mockall::*; |
164 | //! # use std::rc::Rc; |
165 | //! #[automock] |
166 | //! trait Foo { |
167 | //! fn foo(&self, x: Rc<u32>) -> Rc<u32>; // Rc<u32> isn't Send |
168 | //! } |
169 | //! |
170 | //! # fn main() { |
171 | //! let mut mock = MockFoo::new(); |
172 | //! let x = Rc::new(5); |
173 | //! let argument = x.clone(); |
174 | //! mock.expect_foo() |
175 | //! .withf_st(move |x| *x == argument) |
176 | //! .returning_st(move |_| Rc::new(42u32)); |
177 | //! assert_eq!(42, *mock.foo(x)); |
178 | //! # } |
179 | //! ``` |
180 | //! |
181 | //! ## Matching arguments |
182 | //! |
183 | //! Optionally, expectations may have argument matchers set. A matcher will |
184 | //! verify that the expectation was called with the expected arguments, or panic |
185 | //! otherwise. A matcher is anything that implements the [`Predicate`] trait. |
186 | //! For example: |
187 | //! |
188 | //! ```should_panic |
189 | //! # use mockall::*; |
190 | //! # use mockall::predicate::*; |
191 | //! #[automock] |
192 | //! trait Foo { |
193 | //! fn foo(&self, x: u32); |
194 | //! } |
195 | //! |
196 | //! let mut mock = MockFoo::new(); |
197 | //! mock.expect_foo() |
198 | //! .with(eq(42)) |
199 | //! .return_const(()); |
200 | //! |
201 | //! mock.foo(0); // Panics! |
202 | //! ``` |
203 | //! |
204 | //! See [`predicate`] for a list of Mockall's builtin predicate functions. |
205 | //! For convenience, |
206 | //! [`withf`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf) |
207 | //! is a shorthand for setting the commonly used |
208 | //! [`function`] predicate. The arguments to the predicate function are the |
209 | //! method's arguments, *by reference*. For example: |
210 | //! |
211 | //! ```should_panic |
212 | //! # use mockall::*; |
213 | //! #[automock] |
214 | //! trait Foo { |
215 | //! fn foo(&self, x: u32, y: u32); |
216 | //! } |
217 | //! |
218 | //! # fn main() { |
219 | //! let mut mock = MockFoo::new(); |
220 | //! mock.expect_foo() |
221 | //! .withf(|x: &u32, y: &u32| x == y) |
222 | //! .return_const(()); |
223 | //! |
224 | //! mock.foo(2 + 2, 5); // Panics! |
225 | //! # } |
226 | //! ``` |
227 | //! |
228 | //! ### Matching multiple calls |
229 | //! |
230 | //! Matchers can also be used to discriminate between different invocations of |
231 | //! the same function. Used that way, they can provide different return values |
232 | //! for different arguments. The way this works is that on a method call, all |
233 | //! expectations set on a given method are evaluated in FIFO order. The first |
234 | //! matching expectation is used. Only if none of the expectations match does |
235 | //! Mockall panic. For example: |
236 | //! |
237 | //! ``` |
238 | //! # use mockall::*; |
239 | //! # use mockall::predicate::*; |
240 | //! #[automock] |
241 | //! trait Foo { |
242 | //! fn foo(&self, x: u32) -> u32; |
243 | //! } |
244 | //! |
245 | //! # fn main() { |
246 | //! let mut mock = MockFoo::new(); |
247 | //! mock.expect_foo() |
248 | //! .with(eq(5)) |
249 | //! .return_const(50u32); |
250 | //! mock.expect_foo() |
251 | //! .with(eq(6)) |
252 | //! .return_const(60u32); |
253 | //! # } |
254 | //! ``` |
255 | //! |
256 | //! One common pattern is to use multiple expectations in order of decreasing |
257 | //! specificity. The last expectation can provide a default or fallback value, |
258 | //! and earlier ones can be more specific. For example: |
259 | //! |
260 | //! ``` |
261 | //! # use mockall::*; |
262 | //! # use mockall::predicate::*; |
263 | //! #[automock] |
264 | //! trait Foo { |
265 | //! fn open(&self, path: String) -> Option<u32>; |
266 | //! } |
267 | //! |
268 | //! let mut mock = MockFoo::new(); |
269 | //! mock.expect_open() |
270 | //! .with(eq(String::from("something.txt" ))) |
271 | //! .returning(|_| Some(5)); |
272 | //! mock.expect_open() |
273 | //! .return_const(None); |
274 | //! ``` |
275 | //! |
276 | //! ## Call counts |
277 | //! |
278 | //! By default, every expectation is allowed to be called an unlimited number of |
279 | //! times. But Mockall can optionally verify that an expectation was called a |
280 | //! fixed number of times, or any number of times within a given range. |
281 | //! |
282 | //! ```should_panic |
283 | //! # use mockall::*; |
284 | //! # use mockall::predicate::*; |
285 | //! #[automock] |
286 | //! trait Foo { |
287 | //! fn foo(&self, x: u32); |
288 | //! } |
289 | //! |
290 | //! let mut mock = MockFoo::new(); |
291 | //! mock.expect_foo() |
292 | //! .times(1) |
293 | //! .return_const(()); |
294 | //! |
295 | //! mock.foo(0); // Ok |
296 | //! mock.foo(1); // Panics! |
297 | //! ``` |
298 | //! |
299 | //! See also |
300 | //! [`never`](examples::__mock_MockFoo_Foo::__foo::Expectation::never) and |
301 | //! [`times`](examples::__mock_MockFoo_Foo::__foo::Expectation::times). |
302 | //! |
303 | //! ## Sequences |
304 | //! |
305 | //! By default expectations may be matched in any order. But it's possible to |
306 | //! specify the order by using a [`Sequence`]. Any expectations may be added to |
307 | //! the same sequence. They don't even need to come from the same object. |
308 | //! |
309 | //! ```should_panic(expected = "Method sequence violation") |
310 | //! # use mockall::*; |
311 | //! #[automock] |
312 | //! trait Foo { |
313 | //! fn foo(&self); |
314 | //! } |
315 | //! |
316 | //! # fn main() { |
317 | //! let mut seq = Sequence::new(); |
318 | //! |
319 | //! let mut mock1 = MockFoo::new(); |
320 | //! mock1.expect_foo() |
321 | //! .times(1) |
322 | //! .in_sequence(&mut seq) |
323 | //! .returning(|| ()); |
324 | //! |
325 | //! let mut mock2 = MockFoo::new(); |
326 | //! mock2.expect_foo() |
327 | //! .times(1) |
328 | //! .in_sequence(&mut seq) |
329 | //! .returning(|| ()); |
330 | //! |
331 | //! mock2.foo(); // Panics! mock1.foo should've been called first. |
332 | //! # } |
333 | //! ``` |
334 | //! |
335 | //! ## Checkpoints |
336 | //! |
337 | //! Sometimes its useful to validate all expectations mid-test, throw them away, |
338 | //! and add new ones. That's what checkpoints do. Every mock object has a |
339 | //! `checkpoint` method. When called, it will immediately validate all methods' |
340 | //! expectations. So any expectations that haven't satisfied their call count |
341 | //! will panic. Afterwards, those expectations will be cleared so you can add |
342 | //! new expectations and keep testing. |
343 | //! |
344 | //! ```should_panic |
345 | //! # use mockall::*; |
346 | //! #[automock] |
347 | //! trait Foo { |
348 | //! fn foo(&self); |
349 | //! } |
350 | //! |
351 | //! let mut mock = MockFoo::new(); |
352 | //! mock.expect_foo() |
353 | //! .times(2) |
354 | //! .returning(|| ()); |
355 | //! |
356 | //! mock.foo(); |
357 | //! mock.checkpoint(); // Panics! foo hasn't yet been called twice. |
358 | //! ``` |
359 | //! |
360 | //! ```should_panic |
361 | //! # use mockall::*; |
362 | //! #[automock] |
363 | //! trait Foo { |
364 | //! fn foo(&self); |
365 | //! } |
366 | //! |
367 | //! # fn main() { |
368 | //! let mut mock = MockFoo::new(); |
369 | //! mock.expect_foo() |
370 | //! .times(1) |
371 | //! .returning(|| ()); |
372 | //! |
373 | //! mock.foo(); |
374 | //! mock.checkpoint(); |
375 | //! mock.foo(); // Panics! The expectation has been cleared. |
376 | //! # } |
377 | //! ``` |
378 | //! |
379 | //! ## Reference arguments |
380 | //! |
381 | //! Mockall can mock methods with reference arguments, too. There's one catch: |
382 | //! the matcher [`Predicate`] will take reference arguments by value, not by |
383 | //! reference. |
384 | //! |
385 | //! ``` |
386 | //! # use mockall::*; |
387 | //! #[automock] |
388 | //! trait Foo { |
389 | //! fn foo(&self, x: &u32) -> u32; |
390 | //! } |
391 | //! |
392 | //! let mut mock = MockFoo::new(); |
393 | //! let e = mock.expect_foo() |
394 | //! // Note that x is a &u32, not a &&u32 |
395 | //! .withf(|x: &u32| *x == 5) |
396 | //! .returning(|x: &u32| *x + 1); |
397 | //! |
398 | //! assert_eq!(6, mock.foo(&5)); |
399 | //! ``` |
400 | //! |
401 | //! ## Reference return values |
402 | //! |
403 | //! Mockall can also use reference return values. There is one restriction: the |
404 | //! lifetime of the returned reference must be either the same as the lifetime |
405 | //! of the mock object, or `'static`. |
406 | //! |
407 | //! Mockall creates different expectation types for methods that return |
408 | //! references. Their API is the same as the basic `Expectation`, except for |
409 | //! setting return values. |
410 | //! |
411 | //! Methods that return `'static` references work just like methods that return |
412 | //! any other `'static` value. |
413 | //! ``` |
414 | //! # use mockall::*; |
415 | //! struct Thing(u32); |
416 | //! |
417 | //! #[automock] |
418 | //! trait Container { |
419 | //! fn get(&self, i: u32) -> &'static Thing; |
420 | //! } |
421 | //! |
422 | //! # fn main() { |
423 | //! const THING: Thing = Thing(42); |
424 | //! let mut mock = MockContainer::new(); |
425 | //! mock.expect_get() |
426 | //! .return_const(&THING); |
427 | //! |
428 | //! assert_eq!(42, mock.get(0).0); |
429 | //! # } |
430 | //! ``` |
431 | //! |
432 | //! Methods that take a `&self` argument use an `Expectation` class like |
433 | //! [this](examples::__mock_MockFoo_Foo::__bar::Expectation), |
434 | //! which |
435 | //! gets its return value from the |
436 | //! [`return_const`](examples::__mock_MockFoo_Foo::__bar::Expectation::return_const) method. |
437 | //! |
438 | //! ``` |
439 | //! # use mockall::*; |
440 | //! struct Thing(u32); |
441 | //! |
442 | //! #[automock] |
443 | //! trait Container { |
444 | //! fn get(&self, i: u32) -> &Thing; |
445 | //! } |
446 | //! |
447 | //! # fn main() { |
448 | //! let thing = Thing(42); |
449 | //! let mut mock = MockContainer::new(); |
450 | //! mock.expect_get() |
451 | //! .return_const(thing); |
452 | //! |
453 | //! assert_eq!(42, mock.get(0).0); |
454 | //! # } |
455 | //! ``` |
456 | //! |
457 | //! Methods that take a `&mut self` argument use an `Expectation` class like |
458 | //! [this](examples::__mock_MockFoo_Foo::__baz::Expectation), |
459 | //! class, regardless of whether the return value is actually mutable. They can |
460 | //! take their return value either from the |
461 | //! [`return_var`](examples::__mock_MockFoo_Foo::__baz::Expectation::return_var) |
462 | //! or |
463 | //! [`returning`](examples::__mock_MockFoo_Foo::__baz::Expectation::returning) |
464 | //! methods. |
465 | //! |
466 | //! ``` |
467 | //! # use mockall::*; |
468 | //! struct Thing(u32); |
469 | //! |
470 | //! #[automock] |
471 | //! trait Container { |
472 | //! fn get_mut(&mut self, i: u32) -> &mut Thing; |
473 | //! } |
474 | //! |
475 | //! # fn main() { |
476 | //! let thing = Thing(42); |
477 | //! let mut mock = MockContainer::new(); |
478 | //! mock.expect_get_mut() |
479 | //! .return_var(thing); |
480 | //! |
481 | //! mock.get_mut(0).0 = 43; |
482 | //! assert_eq!(43, mock.get_mut(0).0); |
483 | //! # } |
484 | //! ``` |
485 | //! |
486 | //! Unsized types that are common targets for |
487 | //! [`Deref`](core::ops::Deref) |
488 | //! are special. Mockall |
489 | //! will automatically use the type's owned form for the Expectation. |
490 | //! Currently, the |
491 | //! [`CStr`](std::ffi::CStr), |
492 | //! [`OsStr`](std::ffi::OsStr), |
493 | //! [`Path`](std::path::Path), |
494 | //! [`Slice`][std::slice], |
495 | //! and |
496 | //! [`str`](std::str) |
497 | //! types are supported. Using this feature is automatic: |
498 | //! |
499 | //! ``` |
500 | //! # use mockall::*; |
501 | //! #[automock] |
502 | //! trait Foo { |
503 | //! fn name(&self) -> &str; |
504 | //! } |
505 | //! |
506 | //! let mut mock = MockFoo::new(); |
507 | //! mock.expect_name().return_const("abcd" .to_owned()); |
508 | //! assert_eq!("abcd" , mock.name()); |
509 | //! ``` |
510 | //! |
511 | //! Similarly, Mockall will use a Boxed trait object for the Expectation of |
512 | //! methods that return references to trait objects. |
513 | //! |
514 | //! ``` |
515 | //! # use mockall::*; |
516 | //! # use std::fmt::Display; |
517 | //! #[automock] |
518 | //! trait Foo { |
519 | //! fn name(&self) -> &dyn Display; |
520 | //! } |
521 | //! |
522 | //! # fn main() { |
523 | //! let mut mock = MockFoo::new(); |
524 | //! mock.expect_name().return_const(Box::new("abcd" )); |
525 | //! assert_eq!("abcd" , format!("{}" , mock.name())); |
526 | //! # } |
527 | //! ``` |
528 | //! |
529 | //! |
530 | //! ## Impl Trait |
531 | //! |
532 | //! Rust 1.26.0 introduced the `impl Trait` feature. It allows functions to |
533 | //! return concrete but unnamed types (and, less usefully, to take them as |
534 | //! arguments). It's *almost* the same as `Box<dyn Trait>` but without the |
535 | //! extra allocation. Mockall supports deriving mocks for methods that return |
536 | //! `impl Trait`, with limitations. When you derive the mock for such a method, |
537 | //! Mockall internally transforms the Expectation's return type to `Box<dyn |
538 | //! Trait>`, without changing the mock method's signature. So you can use it |
539 | //! like this: |
540 | //! |
541 | //! ``` |
542 | //! # use mockall::*; |
543 | //! # use std::fmt::Debug; |
544 | //! struct Foo {} |
545 | //! #[automock] |
546 | //! impl Foo { |
547 | //! fn foo(&self) -> impl Debug { |
548 | //! // ... |
549 | //! # 4 |
550 | //! } |
551 | //! } |
552 | //! |
553 | //! # fn main() { |
554 | //! let mut mock = MockFoo::new(); |
555 | //! mock.expect_foo() |
556 | //! .returning(|| Box::new(String::from("Hello, World!" ))); |
557 | //! println!("{:?}" , mock.foo()); |
558 | //! # } |
559 | //! ``` |
560 | //! |
561 | //! However, `impl Trait` isn't *exactly* equivalent to `Box<dyn Trait>` but |
562 | //! with fewer allocations. There are some things the former can do but the |
563 | //! latter can't. For one thing, you can't build a trait object out of a |
564 | //! `Sized` trait. So this won't work: |
565 | //! |
566 | //! ```compile_fail |
567 | //! # use mockall::*; |
568 | //! struct Foo {} |
569 | //! #[automock] |
570 | //! impl Foo { |
571 | //! fn foo(&self) -> impl Clone { |
572 | //! // ... |
573 | //! # 4 |
574 | //! } |
575 | //! } |
576 | //! ``` |
577 | //! |
578 | //! Nor can you create a trait object that implements two or more non-auto |
579 | //! types. So this won't work either: |
580 | //! |
581 | //! ```compile_fail |
582 | //! # use mockall::*; |
583 | //! struct Foo {} |
584 | //! #[automock] |
585 | //! impl Foo { |
586 | //! fn foo(&self) -> impl Debug + Display { |
587 | //! // ... |
588 | //! # 4 |
589 | //! } |
590 | //! } |
591 | //! ``` |
592 | //! |
593 | //! For such cases, there is no magic bullet. The best way to mock methods like |
594 | //! those would be to refactor them to return named (but possibly opaque) types |
595 | //! instead. |
596 | //! |
597 | //! See Also [`impl-trait-for-returning-complex-types-with-ease.html`](https://rust-lang-nursery.github.io/edition-guide/rust-2018/trait-system/impl-trait-for-returning-complex-types-with-ease) |
598 | //! |
599 | //! ### impl Future |
600 | //! |
601 | //! Rust 1.36.0 added the `Future` trait. Unlike virtually every trait that |
602 | //! preceeded it, `Box<dyn Future>` is mostly useless. Instead, you usually |
603 | //! need a `Pin<Box<dyn Future>>`. So that's what Mockall will do when you mock |
604 | //! a method returning `impl Future` or the related `impl Stream`. Just |
605 | //! remember to use `pin` in your expectations, like this: |
606 | //! |
607 | //! ``` |
608 | //! # use mockall::*; |
609 | //! # use std::fmt::Debug; |
610 | //! # use futures::{Future, future}; |
611 | //! struct Foo {} |
612 | //! #[automock] |
613 | //! impl Foo { |
614 | //! fn foo(&self) -> impl Future<Output=i32> { |
615 | //! // ... |
616 | //! # future::ready(42) |
617 | //! } |
618 | //! } |
619 | //! |
620 | //! # fn main() { |
621 | //! let mut mock = MockFoo::new(); |
622 | //! mock.expect_foo() |
623 | //! .returning(|| Box::pin(future::ready(42))); |
624 | //! # } |
625 | //! ``` |
626 | //! |
627 | //! ## Mocking structs |
628 | //! |
629 | //! Mockall mocks structs as well as traits. The problem here is a namespace |
630 | //! problem: it's hard to supply the mock object to your code under test, |
631 | //! because it has a different name. The solution is to alter import paths |
632 | //! during test. The easiest way to do that is with the |
633 | //! [`mockall_double`](https://docs.rs/mockall_double/latest) crate. |
634 | //! |
635 | //! [`#[automock]`](attr.automock.html) |
636 | //! works for structs that have a single `impl` block: |
637 | //! ```no_run |
638 | //! use mockall_double::double; |
639 | //! mod thing { |
640 | //! use mockall::automock; |
641 | //! pub struct Thing{} |
642 | //! #[automock] |
643 | //! impl Thing { |
644 | //! pub fn foo(&self) -> u32 { |
645 | //! // ... |
646 | //! # unimplemented!() |
647 | //! } |
648 | //! } |
649 | //! } |
650 | //! |
651 | //! #[double] |
652 | //! use thing::Thing; |
653 | //! |
654 | //! fn do_stuff(thing: &Thing) -> u32 { |
655 | //! thing.foo() |
656 | //! } |
657 | //! |
658 | //! #[cfg(test)] |
659 | //! mod t { |
660 | //! use super::*; |
661 | //! |
662 | //! #[test] |
663 | //! fn test_foo() { |
664 | //! let mut mock = Thing::default(); |
665 | //! mock.expect_foo().returning(|| 42); |
666 | //! do_stuff(&mock); |
667 | //! } |
668 | //! } |
669 | //! # fn main() {} |
670 | //! ``` |
671 | //! For structs with more than one `impl` block or that have unsupported |
672 | //! `#[derive(X)]` attributes, e.g. `Clone`, see [`mock!`] instead. |
673 | //! |
674 | //! ## Generic methods |
675 | //! |
676 | //! Generic methods can be mocked, too. Effectively each generic method is an |
677 | //! infinite set of regular methods, and each of those works just like any other |
678 | //! regular method. The expect_* method is generic, too, and usually must be |
679 | //! called with a turbofish. The only restrictions on mocking generic methods |
680 | //! are that all generic parameters must be `'static`, and generic lifetime |
681 | //! parameters are not allowed. |
682 | //! |
683 | //! ``` |
684 | //! # use mockall::*; |
685 | //! #[automock] |
686 | //! trait Foo { |
687 | //! fn foo<T: 'static>(&self, t: T) -> i32; |
688 | //! } |
689 | //! |
690 | //! let mut mock = MockFoo::new(); |
691 | //! mock.expect_foo::<i16>() |
692 | //! .returning(|t| i32::from(t)); |
693 | //! mock.expect_foo::<i8>() |
694 | //! .returning(|t| -i32::from(t)); |
695 | //! |
696 | //! assert_eq!(5, mock.foo(5i16)); |
697 | //! assert_eq!(-5, mock.foo(5i8)); |
698 | //! ``` |
699 | //! |
700 | //! ## Methods with generic lifetimes |
701 | //! |
702 | //! A method with a lifetime parameter is technically a generic method, but |
703 | //! Mockall treats it like a non-generic method that must work for all possible |
704 | //! lifetimes. Mocking such a method is similar to mocking a non-generic |
705 | //! method, with a few additional restrictions. One restriction is that you |
706 | //! can't match calls with `with`, you must use `withf` instead. Another is |
707 | //! that the generic lifetime may not appear as part of the return type. |
708 | //! Finally, no method may have both generic lifetime parameters *and* generic |
709 | //! type parameters. |
710 | //! |
711 | //! ``` |
712 | //! # use mockall::*; |
713 | //! struct X<'a>(&'a i32); |
714 | //! |
715 | //! #[automock] |
716 | //! trait Foo { |
717 | //! fn foo<'a>(&self, x: X<'a>) -> i32; |
718 | //! } |
719 | //! |
720 | //! # fn main() { |
721 | //! let mut mock = MockFoo::new(); |
722 | //! mock.expect_foo() |
723 | //! .withf(|f| *f.0 == 5) |
724 | //! .return_const(42); |
725 | //! let x = X(&5); |
726 | //! assert_eq!(42, mock.foo(x)); |
727 | //! # } |
728 | //! ``` |
729 | //! |
730 | //! ## Generic traits and structs |
731 | //! |
732 | //! Mocking generic structs and generic traits is not a problem. The mock |
733 | //! struct will be generic, too. The same restrictions apply as with mocking |
734 | //! generic methods: each generic parameter must be `'static`, and generic |
735 | //! lifetime parameters are not allowed. |
736 | //! |
737 | //! ``` |
738 | //! # use mockall::*; |
739 | //! #[automock] |
740 | //! trait Foo<T: 'static> { |
741 | //! fn foo(&self, t: T) -> i32; |
742 | //! } |
743 | //! |
744 | //! # fn main() { |
745 | //! let mut mock = MockFoo::<i16>::new(); |
746 | //! mock.expect_foo() |
747 | //! .returning(|t| i32::from(t)); |
748 | //! assert_eq!(5, mock.foo(5i16)); |
749 | //! # } |
750 | //! ``` |
751 | //! |
752 | //! ## Associated types |
753 | //! |
754 | //! Traits with associated types can be mocked too. Unlike generic traits, the |
755 | //! mock struct will not be generic. Instead, you must specify the associated |
756 | //! types when defining the mock struct. They're specified as metaitems to the |
757 | //! [`#[automock]`](attr.automock.html) attribute. |
758 | //! |
759 | //! ``` |
760 | //! # use mockall::*; |
761 | //! #[automock(type Key=u16; type Value=i32;)] |
762 | //! pub trait A { |
763 | //! type Key; |
764 | //! type Value; |
765 | //! fn foo(&self, k: Self::Key) -> Self::Value; |
766 | //! } |
767 | //! |
768 | //! let mut mock = MockA::new(); |
769 | //! mock.expect_foo() |
770 | //! .returning(|x: u16| i32::from(x)); |
771 | //! assert_eq!(4, mock.foo(4)); |
772 | //! ``` |
773 | //! |
774 | //! ## Multiple and inherited traits |
775 | //! |
776 | //! Creating a mock struct that implements multiple traits, whether inherited or |
777 | //! not, requires using the [`mock!`] macro. But once created, |
778 | //! using it is just the same as using any other mock object: |
779 | //! |
780 | //! ``` |
781 | //! # use mockall::*; |
782 | //! pub trait A { |
783 | //! fn foo(&self); |
784 | //! } |
785 | //! |
786 | //! pub trait B: A { |
787 | //! fn bar(&self); |
788 | //! } |
789 | //! |
790 | //! mock! { |
791 | //! // Structure to mock |
792 | //! C {} |
793 | //! // First trait to implement on C |
794 | //! impl A for C { |
795 | //! fn foo(&self); |
796 | //! } |
797 | //! // Second trait to implement on C |
798 | //! impl B for C { |
799 | //! fn bar(&self); |
800 | //! } |
801 | //! } |
802 | //! # fn main() { |
803 | //! let mut mock = MockC::new(); |
804 | //! mock.expect_foo().returning(|| ()); |
805 | //! mock.expect_bar().returning(|| ()); |
806 | //! mock.foo(); |
807 | //! mock.bar(); |
808 | //! # } |
809 | //! ``` |
810 | //! |
811 | //! ## External traits |
812 | //! |
813 | //! Mockall can mock traits and structs defined in external crates that are |
814 | //! beyond your control, but you must use [`mock!`] instead of |
815 | //! [`#[automock]`](attr.automock.html). Mock an external trait like this: |
816 | //! |
817 | //! ``` |
818 | //! # use mockall::*; |
819 | //! mock! { |
820 | //! MyStruct {} // Name of the mock struct, less the "Mock" prefix |
821 | //! impl Clone for MyStruct { // specification of the trait to mock |
822 | //! fn clone(&self) -> Self; |
823 | //! } |
824 | //! } |
825 | //! |
826 | //! # fn main() { |
827 | //! let mut mock1 = MockMyStruct::new(); |
828 | //! let mock2 = MockMyStruct::new(); |
829 | //! mock1.expect_clone() |
830 | //! .return_once(move || mock2); |
831 | //! let cloned = mock1.clone(); |
832 | //! # } |
833 | //! ``` |
834 | //! |
835 | //! ## Static methods |
836 | //! |
837 | //! Mockall can also mock static methods. But be careful! The expectations are |
838 | //! global. If you want to use a static method in multiple tests, you must |
839 | //! provide your own synchronization. See the [`synchronization |
840 | //! example`](https://github.com/asomers/mockall/blob/master/mockall/examples/synchronization.rs) |
841 | //! for a basic implementation. For ordinary methods, expectations are |
842 | //! set on the mock object. But static methods don't have any mock object. |
843 | //! Instead, you must create a `Context` object just to set their expectations. |
844 | //! |
845 | //! ``` |
846 | //! # use mockall::*; |
847 | //! #[automock] |
848 | //! pub trait A { |
849 | //! fn foo() -> u32; |
850 | //! } |
851 | //! |
852 | //! let ctx = MockA::foo_context(); |
853 | //! ctx.expect().returning(|| 99); |
854 | //! assert_eq!(99, MockA::foo()); |
855 | //! ``` |
856 | //! |
857 | //! A common pattern is mocking a trait with a constructor method. In this case, |
858 | //! you can easily set the mock constructor method to return a mock object. |
859 | //! |
860 | //! ``` |
861 | //! # use mockall::*; |
862 | //! struct Foo{} |
863 | //! #[automock] |
864 | //! impl Foo { |
865 | //! fn from_i32(x: i32) -> Self { |
866 | //! // ... |
867 | //! # unimplemented!() |
868 | //! } |
869 | //! fn foo(&self) -> i32 { |
870 | //! // ... |
871 | //! # unimplemented!() |
872 | //! } |
873 | //! } |
874 | //! |
875 | //! # fn main() { |
876 | //! let ctx = MockFoo::from_i32_context(); |
877 | //! ctx.expect() |
878 | //! .returning(|x| { |
879 | //! let mut mock = MockFoo::default(); |
880 | //! mock.expect_foo() |
881 | //! .return_const(x); |
882 | //! mock |
883 | //! }); |
884 | //! let foo = MockFoo::from_i32(42); |
885 | //! assert_eq!(42, foo.foo()); |
886 | //! # } |
887 | //! ``` |
888 | //! |
889 | //! ### Generic static methods |
890 | //! |
891 | //! Mocking static methods of generic structs or traits, whether or not the |
892 | //! methods themselves are generic, should work seamlessly. |
893 | //! |
894 | //! ``` |
895 | //! # use mockall::*; |
896 | //! #[automock] |
897 | //! trait Foo<T: 'static> { |
898 | //! fn new(t: T) -> MockFoo<T>; |
899 | //! } |
900 | //! |
901 | //! # fn main() { |
902 | //! let ctx = MockFoo::<u32>::new_context(); |
903 | //! ctx.expect() |
904 | //! .returning(|_| MockFoo::default()); |
905 | //! let mock = MockFoo::<u32>::new(42u32); |
906 | //! # } |
907 | //! ``` |
908 | //! |
909 | //! ### Context checkpoints |
910 | //! |
911 | //! The context object cleans up all expectations when it leaves scope. It also |
912 | //! has a `checkpoint` method that functions just like a mock object's |
913 | //! `checkpoint` method. |
914 | //! |
915 | //! ```should_panic |
916 | //! # use mockall::*; |
917 | //! #[automock] |
918 | //! pub trait A { |
919 | //! fn foo() -> u32; |
920 | //! } |
921 | //! |
922 | //! let ctx = MockA::foo_context(); |
923 | //! ctx.expect() |
924 | //! .times(1) |
925 | //! .returning(|| 99); |
926 | //! ctx.checkpoint(); // Panics! |
927 | //! ``` |
928 | //! |
929 | //! A mock object's checkpoint method does *not* checkpoint static methods. |
930 | //! This behavior is useful when using multiple mock objects at once. For |
931 | //! example: |
932 | //! |
933 | //! ``` |
934 | //! # use mockall::*; |
935 | //! #[automock] |
936 | //! pub trait A { |
937 | //! fn build() -> Self; |
938 | //! fn bar(&self) -> i32; |
939 | //! } |
940 | //! |
941 | //! # fn main() { |
942 | //! let ctx = MockA::build_context(); |
943 | //! ctx.expect() |
944 | //! .times(2) |
945 | //! .returning(|| MockA::default()); |
946 | //! let mut mock0 = MockA::build(); |
947 | //! mock0.expect_bar().return_const(4); |
948 | //! mock0.bar(); |
949 | //! mock0.checkpoint(); // Does not checkpoint the build method |
950 | //! let mock1 = MockA::build(); |
951 | //! # } |
952 | //! ``` |
953 | //! |
954 | //! One more thing: Mockall normally creates a zero-argument `new` method for |
955 | //! every mock struct. But it *won't* do that when mocking a struct that |
956 | //! already has a method named `new`. The `default` method will still be |
957 | //! present. |
958 | //! |
959 | //! ## Modules |
960 | //! |
961 | //! In addition to mocking types, Mockall can also derive mocks for |
962 | //! entire modules of Rust functions. Mockall will generate a new module named |
963 | //! "mock_xxx", if "xxx" is the original module's name. You can also use |
964 | //! `#[double]` to selectively import the mock module. |
965 | //! |
966 | //! Be careful! Module functions are static and so have the same caveats as |
967 | //! [static methods](#static-methods) described above. |
968 | //! |
969 | //! ``` |
970 | //! # use mockall::*; |
971 | //! # use mockall_double::*; |
972 | //! mod outer { |
973 | //! use mockall::automock; |
974 | //! #[automock()] |
975 | //! pub(super) mod inner { |
976 | //! pub fn bar(x: u32) -> i64 { |
977 | //! // ... |
978 | //! # 4 |
979 | //! } |
980 | //! } |
981 | //! } |
982 | //! |
983 | //! #[double] |
984 | //! use outer::inner; |
985 | //! |
986 | //! #[cfg(test)] |
987 | //! mod t { |
988 | //! use super::*; |
989 | //! |
990 | //! #[test] |
991 | //! fn test_foo_bar() { |
992 | //! let ctx = inner::bar_context(); |
993 | //! ctx.expect() |
994 | //! .returning(|x| i64::from(x + 1)); |
995 | //! assert_eq!(5, inner::bar(4)); |
996 | //! } |
997 | //! } |
998 | //! # fn main() {} |
999 | //! ``` |
1000 | //! |
1001 | //! ### Foreign functions |
1002 | //! |
1003 | //! One reason to mock modules is when working with foreign functions. Modules |
1004 | //! may contain foreign functions, even though structs and traits may not. Like |
1005 | //! static methods, the expectations are global. |
1006 | //! |
1007 | //! ``` |
1008 | //! # use mockall_double::*; |
1009 | //! mod outer { |
1010 | //! # use mockall::*; |
1011 | //! #[automock] |
1012 | //! pub mod ffi { |
1013 | //! extern "C" { |
1014 | //! pub fn foo(x: u32) -> i64; |
1015 | //! } |
1016 | //! } |
1017 | //! } |
1018 | //! |
1019 | //! #[double] |
1020 | //! use outer::ffi; |
1021 | //! |
1022 | //! fn do_stuff() -> i64 { |
1023 | //! unsafe{ ffi::foo(42) } |
1024 | //! } |
1025 | //! |
1026 | //! #[cfg(test)] |
1027 | //! mod t { |
1028 | //! use super::*; |
1029 | //! |
1030 | //! #[test] |
1031 | //! fn test_foo() { |
1032 | //! let ctx = ffi::foo_context(); |
1033 | //! ctx.expect() |
1034 | //! .returning(|x| i64::from(x + 1)); |
1035 | //! assert_eq!(43, do_stuff()); |
1036 | //! } |
1037 | //! } |
1038 | //! # fn main() {} |
1039 | //! ``` |
1040 | //! |
1041 | //! ## Debug |
1042 | //! |
1043 | //! `#[automock]` will automatically generate `Debug` impls when mocking traits |
1044 | //! and struct impls. `mock!` will too, if you add a `#[derive(Debug)]`, like |
1045 | //! this: |
1046 | //! ```no_run |
1047 | //! # use mockall::*; |
1048 | //! mock! { |
1049 | //! #[derive(Debug)] |
1050 | //! pub Foo {} |
1051 | //! } |
1052 | //! # fn main() { |
1053 | //! # format!("{:?}" , &MockFoo::default()); |
1054 | //! # } |
1055 | //! ``` |
1056 | //! |
1057 | //! ## Async Traits |
1058 | //! |
1059 | //! Async traits aren't yet (as of 1.47.0) a part of the Rust language. But |
1060 | //! they're available from the |
1061 | //! [`async_trait`](https://docs.rs/async-trait/0.1.38/async_trait/) crate. |
1062 | //! Mockall is compatible with this crate, with two important limitations: |
1063 | //! |
1064 | //! * The `#[automock]` attribute must appear _before_ the `#[async_trait]` |
1065 | //! attribute. |
1066 | //! |
1067 | //! * The `#[async_trait]` macro must be imported with its canonical name. |
1068 | //! |
1069 | //! ``` |
1070 | //! # use async_trait::async_trait; |
1071 | //! # use mockall::*; |
1072 | //! // async_trait works with both #[automock] |
1073 | //! #[automock] |
1074 | //! #[async_trait] |
1075 | //! pub trait Foo { |
1076 | //! async fn foo(&self) -> u32; |
1077 | //! } |
1078 | //! // and mock! |
1079 | //! mock! { |
1080 | //! pub Bar {} |
1081 | //! #[async_trait] |
1082 | //! impl Foo for Bar { |
1083 | //! async fn foo(&self) -> u32; |
1084 | //! } |
1085 | //! } |
1086 | //! # fn main() {} |
1087 | //! ``` |
1088 | //! |
1089 | //! ## Crate features |
1090 | //! |
1091 | //! Mockall has a **nightly** feature. Currently this feature has two |
1092 | //! effects: |
1093 | //! |
1094 | //! * The compiler will produce better error messages. |
1095 | //! |
1096 | //! * Expectations for methods whose return type implements `Default` needn't |
1097 | //! have their return values explicitly set. Instead, they will automatically |
1098 | //! return the default value. |
1099 | //! |
1100 | //! With **nightly** enabled, you can omit the return value like this: |
1101 | #![cfg_attr (feature = "nightly" , doc = "```" )] |
1102 | #![cfg_attr (not(feature = "nightly" ), doc = "```should_panic" )] |
1103 | //! # use mockall::*; |
1104 | //! #[automock] |
1105 | //! trait Foo { |
1106 | //! fn foo(&self) -> Vec<u32>; |
1107 | //! } |
1108 | //! |
1109 | //! let mut mock = MockFoo::new(); |
1110 | //! mock.expect_foo(); |
1111 | //! assert!(mock.foo().is_empty()); |
1112 | //! ``` |
1113 | //! |
1114 | //! ## Examples |
1115 | //! |
1116 | //! For additional examples of Mockall in action, including detailed |
1117 | //! documentation on the autogenerated methods, see |
1118 | //! [`examples`](examples). |
1119 | //! |
1120 | //! [`Predicate`]: trait.Predicate.html |
1121 | //! [`Sequence`]: Sequence |
1122 | //! [`cfg-if`]: https://crates.io/crates/cfg-if |
1123 | //! [`function`]: predicate/fn.function.html |
1124 | //! [`mock!`]: macro.mock.html |
1125 | //! [`predicate`]: predicate/index.html |
1126 | |
1127 | #![cfg_attr (feature = "nightly" , feature(specialization))] |
1128 | // Allow the incomplete_feature warning for specialization. We know it's |
1129 | // incomplete; that's why it's guarded by the "nightly" feature. |
1130 | #![cfg_attr (feature = "nightly" , allow(incomplete_features))] |
1131 | |
1132 | #![cfg_attr (feature = "nightly" , feature(doc_cfg))] |
1133 | #![cfg_attr (test, deny(warnings))] |
1134 | #![warn (missing_docs)] |
1135 | |
1136 | use downcast::*; |
1137 | use std::{ |
1138 | any, |
1139 | fmt::{self, Debug, Formatter}, |
1140 | marker::PhantomData, |
1141 | ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, |
1142 | RangeToInclusive}, |
1143 | sync::{ |
1144 | Arc, |
1145 | atomic::{AtomicUsize, Ordering} |
1146 | }, |
1147 | }; |
1148 | |
1149 | #[doc (hidden)] |
1150 | pub use downcast::{Any, Downcast}; |
1151 | #[doc (hidden)] |
1152 | pub use fragile::Fragile; |
1153 | |
1154 | /// For mocking static methods |
1155 | #[doc (hidden)] |
1156 | pub use lazy_static::lazy_static; |
1157 | |
1158 | pub use predicates::{ |
1159 | boolean::PredicateBooleanExt, |
1160 | prelude::{ |
1161 | Predicate, PredicateBoxExt, PredicateFileContentExt, PredicateStrExt, |
1162 | predicate |
1163 | } |
1164 | }; |
1165 | #[doc (hidden)] |
1166 | pub use predicates_tree::CaseTreeExt; |
1167 | |
1168 | #[cfg (doc)] |
1169 | extern crate self as mockall; |
1170 | #[cfg (doc)] |
1171 | pub mod examples; |
1172 | |
1173 | /// Automatically generate mock types for structs and traits. |
1174 | /// |
1175 | /// This is by far the easiest way to use Mockall. It works on almost all |
1176 | /// traits, and almost all structs that have a single `impl` block. In either |
1177 | /// case, it will generate a mock struct whose name is the name of the mocked |
1178 | /// struct/trait prepended with "Mock". For each method of the original, the |
1179 | /// mock struct will have a method named `expect_whatever` that allows you to |
1180 | /// set expectations. There will also be one `checkpoint` method that calls |
1181 | /// [`checkpoint`] for every single mocked method. |
1182 | /// |
1183 | /// # Examples |
1184 | /// |
1185 | /// The simplest use case is mocking a no-frills trait |
1186 | /// ``` |
1187 | /// # use mockall_derive::*; |
1188 | /// #[automock] |
1189 | /// pub trait Foo { |
1190 | /// fn foo(&self, key: i16); |
1191 | /// } |
1192 | /// |
1193 | /// let mock = MockFoo::new(); |
1194 | /// ``` |
1195 | /// |
1196 | /// Mocking a structure: |
1197 | /// ``` |
1198 | /// # use mockall_derive::*; |
1199 | /// struct Foo {} |
1200 | /// #[automock] |
1201 | /// impl Foo { |
1202 | /// fn foo(&self) -> u32 { |
1203 | /// // ... |
1204 | /// # unimplemented!() |
1205 | /// } |
1206 | /// } |
1207 | /// ``` |
1208 | /// |
1209 | /// You can also mock a trait impl on a struct: |
1210 | /// ``` |
1211 | /// # use mockall_derive::*; |
1212 | /// pub trait Foo { |
1213 | /// fn foo(&self, key: i16); |
1214 | /// } |
1215 | /// struct Bar{} |
1216 | /// #[automock] |
1217 | /// impl Foo for Bar { |
1218 | /// fn foo(&self, key: i16){ |
1219 | /// // ... |
1220 | /// # unimplemented!() |
1221 | /// } |
1222 | /// } |
1223 | /// |
1224 | /// let mock = MockBar::new(); |
1225 | /// ``` |
1226 | /// |
1227 | /// Mocking a trait with associated types requires adding a metaitem to the |
1228 | /// attribute: |
1229 | /// ``` |
1230 | /// # use mockall_derive::*; |
1231 | /// #[automock(type Item=u32;)] |
1232 | /// trait Foo { |
1233 | /// type Item; |
1234 | /// fn foo(&self) -> Self::Item; |
1235 | /// } |
1236 | /// ``` |
1237 | /// |
1238 | /// Finally, `#[automock]` can also mock foreign functions. This requires |
1239 | /// another metaitem to specify the mock module name. |
1240 | /// |
1241 | /// ``` |
1242 | /// # use mockall_derive::*; |
1243 | /// #[automock(mod mock_ffi;)] |
1244 | /// extern "C" { |
1245 | /// pub fn foo() -> u32; |
1246 | /// } |
1247 | /// ``` |
1248 | /// |
1249 | /// [`checkpoint`]: ../mockall/index.html#checkpoints |
1250 | /// |
1251 | /// # Limitations |
1252 | /// |
1253 | /// `#[automock]` can't handle everything. There are some cases where |
1254 | /// you will need to use [`mock`] instead: |
1255 | /// * Mocking a struct that has multiple `impl` blocks, including |
1256 | /// structs that implement traits. |
1257 | /// * Mocking a struct or trait defined in another crate. |
1258 | /// * Mocking a trait with trait bounds. |
1259 | /// * If the autogenerated "MockFoo" name isn't acceptable, and you want |
1260 | /// to choose your own name for the mock structure. |
1261 | pub use mockall_derive::automock; |
1262 | |
1263 | /// Manually mock a structure. |
1264 | /// |
1265 | /// Sometimes `automock` can't be used. In those cases you can use `mock!`, |
1266 | /// which basically involves repeating the struct's or trait's definitions. |
1267 | /// |
1268 | /// The format is: |
1269 | /// |
1270 | /// * Optional visibility specifier |
1271 | /// * Real structure name and generics fields |
1272 | /// * 0 or more methods of the structure, written without bodies, enclosed in a |
1273 | /// {} block |
1274 | /// * 0 or more impl blocks implementing traits on the structure, also without |
1275 | /// bodies. |
1276 | /// |
1277 | /// # Examples |
1278 | /// |
1279 | /// Mock a trait. This is the simplest use case. |
1280 | /// ``` |
1281 | /// # use mockall_derive::mock; |
1282 | /// trait Foo { |
1283 | /// fn foo(&self, x: u32); |
1284 | /// } |
1285 | /// mock!{ |
1286 | /// pub MyStruct<T: Clone + 'static> { |
1287 | /// fn bar(&self) -> u8; |
1288 | /// } |
1289 | /// impl<T: Clone + 'static> Foo for MyStruct<T> { |
1290 | /// fn foo(&self, x: u32); |
1291 | /// } |
1292 | /// } |
1293 | /// # fn main() {} |
1294 | /// ``` |
1295 | /// Mocking an unsupported `#[derive(X)]` attribute, e.g. `Clone`, is |
1296 | /// similar. |
1297 | /// ``` |
1298 | /// # use mockall_derive::mock; |
1299 | /// #[derive(Clone)] |
1300 | /// struct MyStruct; |
1301 | /// |
1302 | /// mock!{ |
1303 | /// pub MyStruct { |
1304 | /// fn bar(&self); |
1305 | /// } |
1306 | /// impl Clone for MyStruct { |
1307 | /// fn clone(&self) -> Self; |
1308 | /// } |
1309 | /// } |
1310 | /// # fn main() {} |
1311 | /// ``` |
1312 | /// |
1313 | /// When mocking a generic struct's implementation of a generic trait, use the |
1314 | /// same namespace for their generic parameters. For example, if you wanted to |
1315 | /// mock `Rc`, do |
1316 | /// ``` |
1317 | /// # use mockall_derive::mock; |
1318 | /// mock!{ |
1319 | /// pub Rc<T: 'static> {} |
1320 | /// impl<T: 'static> AsRef<T> for Rc<T> { |
1321 | /// fn as_ref(&self) -> &T; |
1322 | /// } |
1323 | /// } |
1324 | /// # fn main() {} |
1325 | /// ``` |
1326 | /// *not* |
1327 | /// ```compile_fail |
1328 | /// # use mockall_derive::mock; |
1329 | /// mock!{ |
1330 | /// pub Rc<Q: 'static> {} |
1331 | /// impl<T: 'static> AsRef<T> for Rc<T> { |
1332 | /// fn as_ref(&self) -> &T; |
1333 | /// } |
1334 | /// } |
1335 | /// # fn main() {} |
1336 | /// ``` |
1337 | /// Associated types can easily be mocked by specifying a concrete type in the |
1338 | /// `mock!{}` invocation. |
1339 | /// ``` |
1340 | /// # use mockall_derive::mock; |
1341 | /// mock!{ |
1342 | /// MyIter {} |
1343 | /// impl Iterator for MyIter { |
1344 | /// type Item=u32; |
1345 | /// |
1346 | /// fn next(&mut self) -> Option<<Self as Iterator>::Item>; |
1347 | /// } |
1348 | /// } |
1349 | /// # fn main() {} |
1350 | /// ``` |
1351 | pub use mockall_derive::mock; |
1352 | |
1353 | #[doc (hidden)] |
1354 | pub trait AnyExpectations : Any + Send + Sync {} |
1355 | downcast!(dyn AnyExpectations); |
1356 | |
1357 | #[doc (hidden)] |
1358 | pub trait ReturnDefault<O> { |
1359 | fn maybe_return_default() -> Option<O>; |
1360 | fn return_default() -> Result<O, &'static str>; |
1361 | } |
1362 | |
1363 | #[derive(Default)] |
1364 | #[doc (hidden)] |
1365 | pub struct DefaultReturner<O>(PhantomData<O>); |
1366 | |
1367 | ::cfg_if::cfg_if! { |
1368 | if #[cfg(feature = "nightly" )] { |
1369 | impl<O> ReturnDefault<O> for DefaultReturner<O> { |
1370 | default fn maybe_return_default() -> Option<O> { |
1371 | None |
1372 | } |
1373 | |
1374 | default fn return_default() -> Result<O, &'static str> { |
1375 | Err("Can only return default values for types that impl std::Default" ) |
1376 | } |
1377 | } |
1378 | |
1379 | impl<O: Default> ReturnDefault<O> for DefaultReturner<O> { |
1380 | fn maybe_return_default() -> Option<O> { |
1381 | Some(O::default()) |
1382 | } |
1383 | |
1384 | fn return_default() -> Result<O, &'static str> { |
1385 | Ok(O::default()) |
1386 | } |
1387 | } |
1388 | } else { |
1389 | impl<O> ReturnDefault<O> for DefaultReturner<O> { |
1390 | fn maybe_return_default() -> Option<O> { |
1391 | None |
1392 | } |
1393 | |
1394 | fn return_default() -> Result<O, &'static str> { |
1395 | Err("Returning default values requires the \"nightly \" feature" ) |
1396 | } |
1397 | } |
1398 | } |
1399 | } |
1400 | |
1401 | #[doc (hidden)] |
1402 | pub struct MaybeDebugger<'a, T>(pub &'a T); |
1403 | ::cfg_if::cfg_if! { |
1404 | if #[cfg(feature = "nightly" )] { |
1405 | impl<'a, T> Debug for MaybeDebugger<'a, T> { |
1406 | default fn fmt(&self, f: &mut Formatter<'_>) |
1407 | -> Result<(), fmt::Error> |
1408 | { |
1409 | write!(f, "?" ) |
1410 | } |
1411 | } |
1412 | impl<'a, T: Debug> Debug for MaybeDebugger<'a, T> { |
1413 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { |
1414 | self.0.fmt(f) |
1415 | } |
1416 | } |
1417 | } else { |
1418 | impl<'a, T> Debug for MaybeDebugger<'a, T> { |
1419 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { |
1420 | write!(f, "?" ) |
1421 | } |
1422 | } |
1423 | } |
1424 | } |
1425 | |
1426 | // Though it's not entirely correct, we treat usize::max_value() as |
1427 | // approximately infinity. |
1428 | #[derive(Debug)] |
1429 | #[doc (hidden)] |
1430 | pub struct TimesRange(Range<usize>); |
1431 | |
1432 | impl Default for TimesRange { |
1433 | fn default() -> TimesRange { |
1434 | // By default, allow any number of calls |
1435 | TimesRange(0..usize::max_value()) |
1436 | } |
1437 | } |
1438 | |
1439 | impl From<usize> for TimesRange { |
1440 | fn from(n: usize) -> TimesRange { |
1441 | TimesRange(n..(n+1)) |
1442 | } |
1443 | } |
1444 | |
1445 | impl From<Range<usize>> for TimesRange { |
1446 | fn from(r: Range<usize>) -> TimesRange { |
1447 | assert!(r.end > r.start, "Backwards range" ); |
1448 | TimesRange(r) |
1449 | } |
1450 | } |
1451 | |
1452 | impl From<RangeFrom<usize>> for TimesRange { |
1453 | fn from(r: RangeFrom<usize>) -> TimesRange { |
1454 | TimesRange(r.start..usize::max_value()) |
1455 | } |
1456 | } |
1457 | |
1458 | impl From<RangeFull> for TimesRange { |
1459 | fn from(_: RangeFull) -> TimesRange { |
1460 | TimesRange(0..usize::max_value()) |
1461 | } |
1462 | } |
1463 | |
1464 | impl From<RangeInclusive<usize>> for TimesRange { |
1465 | fn from(r: RangeInclusive<usize>) -> TimesRange { |
1466 | assert!(r.end() >= r.start(), "Backwards range" ); |
1467 | TimesRange(*r.start()..*r.end() + 1) |
1468 | } |
1469 | } |
1470 | |
1471 | impl From<RangeTo<usize>> for TimesRange { |
1472 | fn from(r: RangeTo<usize>) -> TimesRange { |
1473 | TimesRange(0..r.end) |
1474 | } |
1475 | } |
1476 | |
1477 | impl From<RangeToInclusive<usize>> for TimesRange { |
1478 | fn from(r: RangeToInclusive<usize>) -> TimesRange { |
1479 | TimesRange(0..r.end + 1) |
1480 | } |
1481 | } |
1482 | |
1483 | #[derive(PartialEq)] |
1484 | #[doc (hidden)] |
1485 | pub enum ExpectedCalls { |
1486 | Satisfied, |
1487 | TooMany, |
1488 | TooFew, |
1489 | } |
1490 | |
1491 | #[derive(Debug, Default)] |
1492 | #[doc (hidden)] |
1493 | pub struct Times{ |
1494 | /// How many times has the expectation already been called? |
1495 | count: AtomicUsize, |
1496 | range: TimesRange |
1497 | } |
1498 | |
1499 | #[doc (hidden)] |
1500 | impl Times { |
1501 | pub fn call(&self) -> Result<(), String> { |
1502 | let count = self.count.fetch_add(1, Ordering::Relaxed) + 1; |
1503 | if count >= self.range.0.end { |
1504 | if self.range.0.end == 1 { |
1505 | Err("should not have been called" .to_owned()) |
1506 | } else { |
1507 | Err(format!( |
1508 | "called {} times which is more than the expected {}" , |
1509 | count, |
1510 | self.range.0.end - 1 |
1511 | )) |
1512 | } |
1513 | } else { |
1514 | Ok(()) |
1515 | } |
1516 | } |
1517 | |
1518 | pub fn any(&mut self) { |
1519 | self.range.0 = 0..usize::max_value(); |
1520 | } |
1521 | |
1522 | /// Return how many times this expectation has been called |
1523 | pub fn count(&self) -> usize { |
1524 | self.count.load(Ordering::Relaxed) |
1525 | } |
1526 | |
1527 | /// Has this expectation already been called the maximum allowed number of |
1528 | /// times? |
1529 | pub fn is_done(&self) -> bool { |
1530 | self.count.load(Ordering::Relaxed) >= self.range.0.end - 1 |
1531 | } |
1532 | |
1533 | /// Is it required that this expectation be called an exact number of times, |
1534 | /// or may it be satisfied by a range of call counts? |
1535 | pub fn is_exact(&self) -> bool { |
1536 | (self.range.0.end - self.range.0.start) == 1 |
1537 | } |
1538 | |
1539 | /// Has this expectation already been called the expected number of times? |
1540 | /// If not, was it too many or too few? |
1541 | pub fn is_satisfied(&self) -> ExpectedCalls { |
1542 | let satisfied_lower_bound = self.count.load(Ordering::Relaxed) >= self.range.0.start; |
1543 | let satisfied_upper_bound = self.count.load(Ordering::Relaxed) < self.range.0.end; |
1544 | if satisfied_lower_bound && satisfied_upper_bound { |
1545 | ExpectedCalls::Satisfied |
1546 | } else if satisfied_lower_bound { |
1547 | ExpectedCalls::TooMany |
1548 | } else { |
1549 | ExpectedCalls::TooFew |
1550 | } |
1551 | } |
1552 | |
1553 | /// The maximum number of times that this expectation must be called |
1554 | pub fn maximum(&self) -> usize { |
1555 | self.range.0.end - 1 |
1556 | } |
1557 | |
1558 | /// The minimum number of times that this expectation must be called |
1559 | pub fn minimum(&self) -> usize { |
1560 | self.range.0.start |
1561 | } |
1562 | |
1563 | // https://github.com/rust-lang/rust-clippy/issues/3307 |
1564 | #[allow (clippy::range_plus_one)] |
1565 | pub fn n(&mut self, n: usize) { |
1566 | self.range.0 = n..(n+1); |
1567 | } |
1568 | |
1569 | pub fn never(&mut self) { |
1570 | self.range.0 = 0..1; |
1571 | } |
1572 | |
1573 | pub fn range(&mut self, range: Range<usize>) { |
1574 | assert!(range.end > range.start, "Backwards range" ); |
1575 | self.range.0 = range; |
1576 | } |
1577 | |
1578 | pub fn times<T: Into<TimesRange>>(&mut self, t: T) { |
1579 | self.range = t.into(); |
1580 | } |
1581 | } |
1582 | |
1583 | /// Non-generic keys to `GenericExpectation` internal storage |
1584 | #[doc (hidden)] |
1585 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] |
1586 | pub struct Key(any::TypeId); |
1587 | |
1588 | #[doc (hidden)] |
1589 | impl Key { |
1590 | pub fn new<T: 'static + ?Sized>() -> Self { |
1591 | Key(any::TypeId::of::<T>()) |
1592 | } |
1593 | } |
1594 | |
1595 | #[doc (hidden)] |
1596 | pub struct SeqHandle { |
1597 | inner: Arc<SeqInner>, |
1598 | seq: usize |
1599 | } |
1600 | |
1601 | impl SeqHandle { |
1602 | /// Tell the Sequence that this expectation has been fully satisfied |
1603 | pub fn satisfy(&self) { |
1604 | self.inner.satisfy(self.seq); |
1605 | } |
1606 | |
1607 | /// Verify that this handle was called in the correct order |
1608 | pub fn verify(&self, desc: &str) { |
1609 | self.inner.verify(self.seq, desc); |
1610 | } |
1611 | } |
1612 | |
1613 | #[derive(Default)] |
1614 | struct SeqInner { |
1615 | satisfaction_level: AtomicUsize, |
1616 | } |
1617 | |
1618 | impl SeqInner { |
1619 | /// Record the call identified by `seq` as fully satisfied. |
1620 | fn satisfy(&self, seq: usize) { |
1621 | let old_sl = self.satisfaction_level.fetch_add(1, Ordering::Relaxed); |
1622 | assert_eq!(old_sl, seq, "Method sequence violation. Was an already-satisfied method called another time?" ); |
1623 | } |
1624 | |
1625 | /// Verify that the call identified by `seq` was called in the correct order |
1626 | fn verify(&self, seq: usize, desc: &str) { |
1627 | assert_eq!(seq, self.satisfaction_level.load(Ordering::Relaxed), |
1628 | "{}: Method sequence violation" , desc) |
1629 | } |
1630 | } |
1631 | |
1632 | /// Used to enforce that mock calls must happen in the sequence specified. |
1633 | /// |
1634 | /// Each expectation must expect to be called a fixed number of times. Once |
1635 | /// satisfied, the next expectation in the sequence will expect to be called. |
1636 | /// |
1637 | /// # Examples |
1638 | /// ``` |
1639 | /// # use mockall::*; |
1640 | /// #[automock] |
1641 | /// trait Foo { |
1642 | /// fn foo(&self); |
1643 | /// fn bar(&self) -> u32; |
1644 | /// } |
1645 | /// let mut seq = Sequence::new(); |
1646 | /// |
1647 | /// let mut mock0 = MockFoo::new(); |
1648 | /// let mut mock1 = MockFoo::new(); |
1649 | /// |
1650 | /// mock0.expect_foo() |
1651 | /// .times(1) |
1652 | /// .returning(|| ()) |
1653 | /// .in_sequence(&mut seq); |
1654 | /// |
1655 | /// mock1.expect_bar() |
1656 | /// .times(1) |
1657 | /// .returning(|| 42) |
1658 | /// .in_sequence(&mut seq); |
1659 | /// |
1660 | /// mock0.foo(); |
1661 | /// mock1.bar(); |
1662 | /// ``` |
1663 | /// |
1664 | /// It is an error to add an expectation to a `Sequence` if its call count is |
1665 | /// unspecified. |
1666 | /// ```should_panic(expected = "with an exact call count") |
1667 | /// # use mockall::*; |
1668 | /// #[automock] |
1669 | /// trait Foo { |
1670 | /// fn foo(&self); |
1671 | /// } |
1672 | /// let mut seq = Sequence::new(); |
1673 | /// |
1674 | /// let mut mock = MockFoo::new(); |
1675 | /// mock.expect_foo() |
1676 | /// .returning(|| ()) |
1677 | /// .in_sequence(&mut seq); // panics! |
1678 | /// ``` |
1679 | #[derive(Default)] |
1680 | pub struct Sequence { |
1681 | inner: Arc<SeqInner>, |
1682 | next_seq: usize, |
1683 | } |
1684 | |
1685 | impl Sequence { |
1686 | /// Create a new empty [`Sequence`] |
1687 | pub fn new() -> Self { |
1688 | Self::default() |
1689 | } |
1690 | |
1691 | /// Not for public consumption, but it must be public so the generated code |
1692 | /// can call it. |
1693 | #[doc (hidden)] |
1694 | pub fn next_handle(&mut self) -> SeqHandle { |
1695 | let handle = SeqHandle{inner: self.inner.clone(), seq: self.next_seq}; |
1696 | self.next_seq += 1; |
1697 | handle |
1698 | } |
1699 | } |
1700 | |