blob: 742efb8163649b2afc353ffe1af4a99ec36eb332 [file] [log] [blame]
// vim: tw=80
//! A powerful mock object library for Rust.
//!
//! Mockall provides tools to create mock versions of almost any trait
//! or struct. They can be used in unit tests as a stand-in for the real
//! object.
//!
//! # Usage
//!
//! There are two ways to use Mockall. The easiest is to use
//! [`#[automock]`](attr.automock.html). It can mock most traits, or structs
//! that only have a single `impl` block. For things it can't handle, there is
//! [`mock!`].
//!
//! Whichever method is used, the basic idea is the same.
//! * Create a mock struct. It's name will be the same as the original, with
//! "Mock" prepended.
//! * In your test, instantiate the mock struct with its `new` or `default`
//! method.
//! * Set expectations on the mock struct. Each expectation can have required
//! argument matchers, a required call count, and a required position in a
//! [`Sequence`]. Each expectation must also have a return value.
//! * Supply the mock object to the code that you're testing. It will return
//! the preprogrammed return values supplied in the previous step. Any
//! accesses contrary to your expectations will cause a panic.
//!
//! # User Guide
//!
//! * [`Getting started`](#getting-started)
//! * [`Static Return values`](#static-return-values)
//! * [`Matching arguments`](#matching-arguments)
//! * [`Call counts`](#call-counts)
//! * [`Sequences`](#sequences)
//! * [`Checkpoints`](#checkpoints)
//! * [`Reference arguments`](#reference-arguments)
//! * [`Reference return values`](#reference-return-values)
//! * [`impl Trait`](#impl-trait)
//! * [`Mocking structs`](#mocking-structs)
//! * [`Generic methods`](#generic-methods)
//! * [`Generic traits and structs`](#generic-traits-and-structs)
//! * [`Associated types`](#associated-types)
//! * [`Multiple and inherited traits`](#multiple-and-inherited-traits)
//! * [`External traits`](#external-traits)
//! * [`Static methods`](#static-methods)
//! * [`Modules`](#modules)
//! * [`Foreign functions`](#foreign-functions)
//! * [`Debug`](#debug)
//! * [`Async Traits`](#async-traits)
//! * [`Crate features`](#crate-features)
//! * [`Examples`](#examples)
//!
//! ## Getting Started
//! ```
//! use mockall::*;
//! use mockall::predicate::*;
//! #[automock]
//! trait MyTrait {
//! fn foo(&self, x: u32) -> u32;
//! }
//!
//! fn call_with_four(x: &dyn MyTrait) -> u32 {
//! x.foo(4)
//! }
//!
//! let mut mock = MockMyTrait::new();
//! mock.expect_foo()
//! .with(predicate::eq(4))
//! .times(1)
//! .returning(|x| x + 1);
//! assert_eq!(5, call_with_four(&mock));
//! ```
//!
//! ## Static Return values
//!
//! Every expectation must have an associated return value (though when the
//! **nightly** feature is enabled expectations will automatically return the
//! default values of their return types, if their return types implement
//! `Default`.). For methods that return a `static` value, the macros will
//! generate an `Expectation` struct like
//! [`this`](examples::__mock_MockFoo_Foo::__foo::Expectation).
//! There are two ways to set such an expectation's return value: with a
//! constant
//! ([`return_const`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const))
//! or a closure
//! ([`returning`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning)).
//! A closure will take the method's arguments by value.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait MyTrait {
//! fn foo(&self) -> u32;
//! fn bar(&self, x: u32, y: u32) -> u32;
//! }
//!
//! let mut mock = MockMyTrait::new();
//! mock.expect_foo()
//! .return_const(42u32);
//! mock.expect_bar()
//! .returning(|x, y| x + y);
//! ```
//!
//! Additionally, constants that aren't `Clone` can be returned with the
//! [`return_once`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once)
//! method.
//!
//! ```
//! # use mockall::*;
//! struct NonClone();
//! #[automock]
//! trait Foo {
//! fn foo(&self) -> NonClone;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! let r = NonClone{};
//! mock.expect_foo()
//! .return_once(move || r);
//! # }
//! ```
//!
//! `return_once` can also be used for computing the return value with an
//! `FnOnce` closure. This is useful for returning a non-`Clone` value and also
//! triggering side effects at the same time.
//!
//! ```
//! # use mockall::*;
//! fn do_something() {}
//!
//! struct NonClone();
//!
//! #[automock]
//! trait Foo {
//! fn foo(&self) -> NonClone;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! let r = NonClone{};
//! mock.expect_foo()
//! .return_once(move || {
//! do_something();
//! r
//! });
//! # }
//! ```
//!
//! Mock objects are always `Send`. If you need to use a return type that
//! isn't, you can use the
//! [`return_const_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const_st),
//! [`returning_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning_st),
//! or
//! [`return_once_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once_st),
//! methods. If you need to match arguments that are not `Send`, you can use the
//! [`withf_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf_st)
//! These take a non-`Send` object and add runtime access checks. The wrapped
//! object will be `Send`, but accessing it from multiple threads will cause a
//! runtime panic.
//!
//! ```
//! # use mockall::*;
//! # use std::rc::Rc;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: Rc<u32>) -> Rc<u32>; // Rc<u32> isn't Send
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! let x = Rc::new(5);
//! let argument = x.clone();
//! mock.expect_foo()
//! .withf_st(move |x| *x == argument)
//! .returning_st(move |_| Rc::new(42u32));
//! assert_eq!(42, *mock.foo(x));
//! # }
//! ```
//!
//! ## Matching arguments
//!
//! Optionally, expectations may have argument matchers set. A matcher will
//! verify that the expectation was called with the expected arguments, or panic
//! otherwise. A matcher is anything that implements the [`Predicate`] trait.
//! For example:
//!
//! ```should_panic
//! # use mockall::*;
//! # use mockall::predicate::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: u32);
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .with(eq(42))
//! .return_const(());
//!
//! mock.foo(0); // Panics!
//! ```
//!
//! See [`predicate`] for a list of Mockall's builtin predicate functions.
//! For convenience,
//! [`withf`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf)
//! is a shorthand for setting the commonly used
//! [`function`] predicate. The arguments to the predicate function are the
//! method's arguments, *by reference*. For example:
//!
//! ```should_panic
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: u32, y: u32);
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .withf(|x: &u32, y: &u32| x == y)
//! .return_const(());
//!
//! mock.foo(2 + 2, 5); // Panics!
//! # }
//! ```
//!
//! ### Matching multiple calls
//!
//! Matchers can also be used to discriminate between different invocations of
//! the same function. Used that way, they can provide different return values
//! for different arguments. The way this works is that on a method call, all
//! expectations set on a given method are evaluated in FIFO order. The first
//! matching expectation is used. Only if none of the expectations match does
//! Mockall panic. For example:
//!
//! ```
//! # use mockall::*;
//! # use mockall::predicate::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: u32) -> u32;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .with(eq(5))
//! .return_const(50u32);
//! mock.expect_foo()
//! .with(eq(6))
//! .return_const(60u32);
//! # }
//! ```
//!
//! One common pattern is to use multiple expectations in order of decreasing
//! specificity. The last expectation can provide a default or fallback value,
//! and earlier ones can be more specific. For example:
//!
//! ```
//! # use mockall::*;
//! # use mockall::predicate::*;
//! #[automock]
//! trait Foo {
//! fn open(&self, path: String) -> Option<u32>;
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_open()
//! .with(eq(String::from("something.txt")))
//! .returning(|_| Some(5));
//! mock.expect_open()
//! .return_const(None);
//! ```
//!
//! ## Call counts
//!
//! By default, every expectation is allowed to be called an unlimited number of
//! times. But Mockall can optionally verify that an expectation was called a
//! fixed number of times, or any number of times within a given range.
//!
//! ```should_panic
//! # use mockall::*;
//! # use mockall::predicate::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: u32);
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .times(1)
//! .return_const(());
//!
//! mock.foo(0); // Ok
//! mock.foo(1); // Panics!
//! ```
//!
//! See also
//! [`never`](examples::__mock_MockFoo_Foo::__foo::Expectation::never) and
//! [`times`](examples::__mock_MockFoo_Foo::__foo::Expectation::times).
//!
//! ## Sequences
//!
//! By default expectations may be matched in any order. But it's possible to
//! specify the order by using a [`Sequence`]. Any expectations may be added to
//! the same sequence. They don't even need to come from the same object.
//!
//! ```should_panic(expected = "Method sequence violation")
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self);
//! }
//!
//! # fn main() {
//! let mut seq = Sequence::new();
//!
//! let mut mock1 = MockFoo::new();
//! mock1.expect_foo()
//! .times(1)
//! .in_sequence(&mut seq)
//! .returning(|| ());
//!
//! let mut mock2 = MockFoo::new();
//! mock2.expect_foo()
//! .times(1)
//! .in_sequence(&mut seq)
//! .returning(|| ());
//!
//! mock2.foo(); // Panics! mock1.foo should've been called first.
//! # }
//! ```
//!
//! ## Checkpoints
//!
//! Sometimes its useful to validate all expectations mid-test, throw them away,
//! and add new ones. That's what checkpoints do. Every mock object has a
//! `checkpoint` method. When called, it will immediately validate all methods'
//! expectations. So any expectations that haven't satisfied their call count
//! will panic. Afterwards, those expectations will be cleared so you can add
//! new expectations and keep testing.
//!
//! ```should_panic
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self);
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .times(2)
//! .returning(|| ());
//!
//! mock.foo();
//! mock.checkpoint(); // Panics! foo hasn't yet been called twice.
//! ```
//!
//! ```should_panic
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self);
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .times(1)
//! .returning(|| ());
//!
//! mock.foo();
//! mock.checkpoint();
//! mock.foo(); // Panics! The expectation has been cleared.
//! # }
//! ```
//!
//! ## Reference arguments
//!
//! Mockall can mock methods with reference arguments, too. There's one catch:
//! the matcher [`Predicate`] will take reference arguments by value, not by
//! reference.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self, x: &u32) -> u32;
//! }
//!
//! let mut mock = MockFoo::new();
//! let e = mock.expect_foo()
//! // Note that x is a &u32, not a &&u32
//! .withf(|x: &u32| *x == 5)
//! .returning(|x: &u32| *x + 1);
//!
//! assert_eq!(6, mock.foo(&5));
//! ```
//!
//! ## Reference return values
//!
//! Mockall can also use reference return values. There is one restriction: the
//! lifetime of the returned reference must be either the same as the lifetime
//! of the mock object, or `'static`.
//!
//! Mockall creates different expectation types for methods that return
//! references. Their API is the same as the basic `Expectation`, except for
//! setting return values.
//!
//! Methods that return `'static` references work just like methods that return
//! any other `'static` value.
//! ```
//! # use mockall::*;
//! struct Thing(u32);
//!
//! #[automock]
//! trait Container {
//! fn get(&self, i: u32) -> &'static Thing;
//! }
//!
//! # fn main() {
//! const THING: Thing = Thing(42);
//! let mut mock = MockContainer::new();
//! mock.expect_get()
//! .return_const(&THING);
//!
//! assert_eq!(42, mock.get(0).0);
//! # }
//! ```
//!
//! Methods that take a `&self` argument use an `Expectation` class like
//! [this](examples::__mock_MockFoo_Foo::__bar::Expectation),
//! which
//! gets its return value from the
//! [`return_const`](examples::__mock_MockFoo_Foo::__bar::Expectation::return_const) method.
//!
//! ```
//! # use mockall::*;
//! struct Thing(u32);
//!
//! #[automock]
//! trait Container {
//! fn get(&self, i: u32) -> &Thing;
//! }
//!
//! # fn main() {
//! let thing = Thing(42);
//! let mut mock = MockContainer::new();
//! mock.expect_get()
//! .return_const(thing);
//!
//! assert_eq!(42, mock.get(0).0);
//! # }
//! ```
//!
//! Methods that take a `&mut self` argument use an `Expectation` class like
//! [this](examples::__mock_MockFoo_Foo::__baz::Expectation),
//! class, regardless of whether the return value is actually mutable. They can
//! take their return value either from the
//! [`return_var`](examples::__mock_MockFoo_Foo::__baz::Expectation::return_var)
//! or
//! [`returning`](examples::__mock_MockFoo_Foo::__baz::Expectation::returning)
//! methods.
//!
//! ```
//! # use mockall::*;
//! struct Thing(u32);
//!
//! #[automock]
//! trait Container {
//! fn get_mut(&mut self, i: u32) -> &mut Thing;
//! }
//!
//! # fn main() {
//! let thing = Thing(42);
//! let mut mock = MockContainer::new();
//! mock.expect_get_mut()
//! .return_var(thing);
//!
//! mock.get_mut(0).0 = 43;
//! assert_eq!(43, mock.get_mut(0).0);
//! # }
//! ```
//!
//! Unsized types that are common targets for
//! [`Deref`](core::ops::Deref)
//! are special. Mockall
//! will automatically use the type's owned form for the Expectation.
//! Currently, the
//! [`CStr`](std::ffi::CStr),
//! [`OsStr`](std::ffi::OsStr),
//! [`Path`](std::path::Path),
//! [`Slice`][std::slice],
//! and
//! [`str`](std::str)
//! types are supported. Using this feature is automatic:
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn name(&self) -> &str;
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_name().return_const("abcd".to_owned());
//! assert_eq!("abcd", mock.name());
//! ```
//!
//! Similarly, Mockall will use a Boxed trait object for the Expectation of
//! methods that return references to trait objects.
//!
//! ```
//! # use mockall::*;
//! # use std::fmt::Display;
//! #[automock]
//! trait Foo {
//! fn name(&self) -> &dyn Display;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_name().return_const(Box::new("abcd"));
//! assert_eq!("abcd", format!("{}", mock.name()));
//! # }
//! ```
//!
//!
//! ## Impl Trait
//!
//! Rust 1.26.0 introduced the `impl Trait` feature. It allows functions to
//! return concrete but unnamed types (and, less usefully, to take them as
//! arguments). It's *almost* the same as `Box<dyn Trait>` but without the
//! extra allocation. Mockall supports deriving mocks for methods that return
//! `impl Trait`, with limitations. When you derive the mock for such a method,
//! Mockall internally transforms the Expectation's return type to `Box<dyn
//! Trait>`, without changing the mock method's signature. So you can use it
//! like this:
//!
//! ```
//! # use mockall::*;
//! # use std::fmt::Debug;
//! struct Foo {}
//! #[automock]
//! impl Foo {
//! fn foo(&self) -> impl Debug {
//! // ...
//! # 4
//! }
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .returning(|| Box::new(String::from("Hello, World!")));
//! println!("{:?}", mock.foo());
//! # }
//! ```
//!
//! However, `impl Trait` isn't *exactly* equivalent to `Box<dyn Trait>` but
//! with fewer allocations. There are some things the former can do but the
//! latter can't. For one thing, you can't build a trait object out of a
//! `Sized` trait. So this won't work:
//!
//! ```compile_fail
//! # use mockall::*;
//! struct Foo {}
//! #[automock]
//! impl Foo {
//! fn foo(&self) -> impl Clone {
//! // ...
//! # 4
//! }
//! }
//! ```
//!
//! Nor can you create a trait object that implements two or more non-auto
//! types. So this won't work either:
//!
//! ```compile_fail
//! # use mockall::*;
//! struct Foo {}
//! #[automock]
//! impl Foo {
//! fn foo(&self) -> impl Debug + Display {
//! // ...
//! # 4
//! }
//! }
//! ```
//!
//! For such cases, there is no magic bullet. The best way to mock methods like
//! those would be to refactor them to return named (but possibly opaque) types
//! instead.
//!
//! 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)
//!
//! ### impl Future
//!
//! Rust 1.36.0 added the `Future` trait. Unlike virtually every trait that
//! preceeded it, `Box<dyn Future>` is mostly useless. Instead, you usually
//! need a `Pin<Box<dyn Future>>`. So that's what Mockall will do when you mock
//! a method returning `impl Future` or the related `impl Stream`. Just
//! remember to use `pin` in your expectations, like this:
//!
//! ```
//! # use mockall::*;
//! # use std::fmt::Debug;
//! # use futures::{Future, future};
//! struct Foo {}
//! #[automock]
//! impl Foo {
//! fn foo(&self) -> impl Future<Output=i32> {
//! // ...
//! # future::ready(42)
//! }
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .returning(|| Box::pin(future::ready(42)));
//! # }
//! ```
//!
//! ## Mocking structs
//!
//! Mockall mocks structs as well as traits. The problem here is a namespace
//! problem: it's hard to supply the mock object to your code under test,
//! because it has a different name. The solution is to alter import paths
//! during test. The easiest way to do that is with the
//! [`mockall_double`](https://docs.rs/mockall_double/latest) crate.
//!
//! [`#[automock]`](attr.automock.html)
//! works for structs that have a single `impl` block:
//! ```no_run
//! use mockall_double::double;
//! mod thing {
//! use mockall::automock;
//! pub struct Thing{}
//! #[automock]
//! impl Thing {
//! pub fn foo(&self) -> u32 {
//! // ...
//! # unimplemented!()
//! }
//! }
//! }
//!
//! #[double]
//! use thing::Thing;
//!
//! fn do_stuff(thing: &Thing) -> u32 {
//! thing.foo()
//! }
//!
//! #[cfg(test)]
//! mod t {
//! use super::*;
//!
//! #[test]
//! fn test_foo() {
//! let mut mock = Thing::default();
//! mock.expect_foo().returning(|| 42);
//! do_stuff(&mock);
//! }
//! }
//! # fn main() {}
//! ```
//! For structs with more than one `impl` block or that have unsupported
//! `#[derive(X)]` attributes, e.g. `Clone`, see [`mock!`] instead.
//!
//! ## Generic methods
//!
//! Mocking generic methods is possible, but the exact process depends on
//! whether the parameters are `'static`, non-`'static`, or lifetimes.
//!
//! ### With static parameters
//!
//! With fully `'static` parameters, the mock method is generic and so is its
//! expect_* method. The expect_* method usually must be called with a
//! turbofish. Expectations set with different generic parameters operate
//! completely independently of one another.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo<T: 'static>(&self, t: T) -> i32;
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_foo::<i16>()
//! .returning(|t| i32::from(t));
//! mock.expect_foo::<i8>()
//! .returning(|t| -i32::from(t));
//!
//! assert_eq!(5, mock.foo(5i16));
//! assert_eq!(-5, mock.foo(5i8));
//! ```
//!
//! ### With non-`static` type parameters
//!
//! Mocking methods with non-`'static` type parameters is harder. The way
//! Mockall does it is by turning the generic parameters into trait objects
//! before evaluating expectations. This makes the expect_* method concrete,
//! rather than generic. It also comes with many restrictions. See
//! [`#[concretize]`](attr.concretize.html) for more details.
//!
//! ### With generic lifetimes
//!
//! A method with a lifetime parameter is technically a generic method, but
//! Mockall treats it like a non-generic method that must work for all possible
//! lifetimes. Mocking such a method is similar to mocking a non-generic
//! method, with a few additional restrictions. One restriction is that you
//! can't match calls with `with`, you must use `withf` instead. Another is
//! that the generic lifetime may not appear as part of the return type.
//! Finally, no method may have both generic lifetime parameters *and* generic
//! type parameters.
//!
//! ```
//! # use mockall::*;
//! struct X<'a>(&'a i32);
//!
//! #[automock]
//! trait Foo {
//! fn foo<'a>(&self, x: X<'a>) -> i32;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::new();
//! mock.expect_foo()
//! .withf(|f| *f.0 == 5)
//! .return_const(42);
//! let x = X(&5);
//! assert_eq!(42, mock.foo(x));
//! # }
//! ```
//!
//! ## Generic traits and structs
//!
//! Mocking generic structs and generic traits is not a problem. The mock
//! struct will be generic, too. The same restrictions apply as with mocking
//! generic methods: each generic parameter must be `'static`, and generic
//! lifetime parameters are not allowed.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait Foo<T: 'static> {
//! fn foo(&self, t: T) -> i32;
//! }
//!
//! # fn main() {
//! let mut mock = MockFoo::<i16>::new();
//! mock.expect_foo()
//! .returning(|t| i32::from(t));
//! assert_eq!(5, mock.foo(5i16));
//! # }
//! ```
//!
//! ## Associated types
//!
//! Traits with associated types can be mocked too. Unlike generic traits, the
//! mock struct will not be generic. Instead, you must specify the associated
//! types when defining the mock struct. They're specified as metaitems to the
//! [`#[automock]`](attr.automock.html) attribute.
//!
//! ```
//! # use mockall::*;
//! #[automock(type Key=u16; type Value=i32;)]
//! pub trait A {
//! type Key;
//! type Value;
//! fn foo(&self, k: Self::Key) -> Self::Value;
//! }
//!
//! let mut mock = MockA::new();
//! mock.expect_foo()
//! .returning(|x: u16| i32::from(x));
//! assert_eq!(4, mock.foo(4));
//! ```
//!
//! ## Multiple and inherited traits
//!
//! Creating a mock struct that implements multiple traits, whether inherited or
//! not, requires using the [`mock!`] macro. But once created,
//! using it is just the same as using any other mock object:
//!
//! ```
//! # use mockall::*;
//! pub trait A {
//! fn foo(&self);
//! }
//!
//! pub trait B: A {
//! fn bar(&self);
//! }
//!
//! mock! {
//! // Structure to mock
//! C {}
//! // First trait to implement on C
//! impl A for C {
//! fn foo(&self);
//! }
//! // Second trait to implement on C
//! impl B for C {
//! fn bar(&self);
//! }
//! }
//! # fn main() {
//! let mut mock = MockC::new();
//! mock.expect_foo().returning(|| ());
//! mock.expect_bar().returning(|| ());
//! mock.foo();
//! mock.bar();
//! # }
//! ```
//!
//! ## External traits
//!
//! Mockall can mock traits and structs defined in external crates that are
//! beyond your control, but you must use [`mock!`] instead of
//! [`#[automock]`](attr.automock.html). Mock an external trait like this:
//!
//! ```
//! # use mockall::*;
//! mock! {
//! MyStruct {} // Name of the mock struct, less the "Mock" prefix
//! impl Clone for MyStruct { // specification of the trait to mock
//! fn clone(&self) -> Self;
//! }
//! }
//!
//! # fn main() {
//! let mut mock1 = MockMyStruct::new();
//! let mock2 = MockMyStruct::new();
//! mock1.expect_clone()
//! .return_once(move || mock2);
//! let cloned = mock1.clone();
//! # }
//! ```
//!
//! ## Static methods
//!
//! Mockall can also mock static methods. But be careful! The expectations are
//! global. If you want to use a static method in multiple tests, you must
//! provide your own synchronization. See the [`synchronization
//! example`](https://github.com/asomers/mockall/blob/master/mockall/examples/synchronization.rs)
//! for a basic implementation. For ordinary methods, expectations are
//! set on the mock object. But static methods don't have any mock object.
//! Instead, you must create a `Context` object just to set their expectations.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! pub trait A {
//! fn foo() -> u32;
//! }
//!
//! let ctx = MockA::foo_context();
//! ctx.expect().returning(|| 99);
//! assert_eq!(99, MockA::foo());
//! ```
//!
//! A common pattern is mocking a trait with a constructor method. In this case,
//! you can easily set the mock constructor method to return a mock object.
//!
//! ```
//! # use mockall::*;
//! struct Foo{}
//! #[automock]
//! impl Foo {
//! fn from_i32(x: i32) -> Self {
//! // ...
//! # unimplemented!()
//! }
//! fn foo(&self) -> i32 {
//! // ...
//! # unimplemented!()
//! }
//! }
//!
//! # fn main() {
//! let ctx = MockFoo::from_i32_context();
//! ctx.expect()
//! .returning(|x| {
//! let mut mock = MockFoo::default();
//! mock.expect_foo()
//! .return_const(x);
//! mock
//! });
//! let foo = MockFoo::from_i32(42);
//! assert_eq!(42, foo.foo());
//! # }
//! ```
//!
//! ### Generic static methods
//!
//! Mocking static methods of generic structs or traits, whether or not the
//! methods themselves are generic, should work seamlessly.
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! trait Foo<T: 'static> {
//! fn new(t: T) -> MockFoo<T>;
//! }
//!
//! # fn main() {
//! let ctx = MockFoo::<u32>::new_context();
//! ctx.expect()
//! .returning(|_| MockFoo::default());
//! let mock = MockFoo::<u32>::new(42u32);
//! # }
//! ```
//!
//! ### Context checkpoints
//!
//! The context object cleans up all expectations when it leaves scope. It also
//! has a `checkpoint` method that functions just like a mock object's
//! `checkpoint` method.
//!
//! ```should_panic
//! # use mockall::*;
//! #[automock]
//! pub trait A {
//! fn foo() -> u32;
//! }
//!
//! let ctx = MockA::foo_context();
//! ctx.expect()
//! .times(1)
//! .returning(|| 99);
//! ctx.checkpoint(); // Panics!
//! ```
//!
//! A mock object's checkpoint method does *not* checkpoint static methods.
//! This behavior is useful when using multiple mock objects at once. For
//! example:
//!
//! ```
//! # use mockall::*;
//! #[automock]
//! pub trait A {
//! fn build() -> Self;
//! fn bar(&self) -> i32;
//! }
//!
//! # fn main() {
//! let ctx = MockA::build_context();
//! ctx.expect()
//! .times(2)
//! .returning(|| MockA::default());
//! let mut mock0 = MockA::build();
//! mock0.expect_bar().return_const(4);
//! mock0.bar();
//! mock0.checkpoint(); // Does not checkpoint the build method
//! let mock1 = MockA::build();
//! # }
//! ```
//!
//! One more thing: Mockall normally creates a zero-argument `new` method for
//! every mock struct. But it *won't* do that when mocking a struct that
//! already has a method named `new`. The `default` method will still be
//! present.
//!
//! ## Modules
//!
//! In addition to mocking types, Mockall can also derive mocks for
//! entire modules of Rust functions. Mockall will generate a new module named
//! "mock_xxx", if "xxx" is the original module's name. You can also use
//! `#[double]` to selectively import the mock module.
//!
//! Be careful! Module functions are static and so have the same caveats as
//! [static methods](#static-methods) described above.
//!
//! ```
//! # use mockall::*;
//! # use mockall_double::*;
//! mod outer {
//! use mockall::automock;
//! #[automock()]
//! pub(super) mod inner {
//! pub fn bar(x: u32) -> i64 {
//! // ...
//! # 4
//! }
//! }
//! }
//!
//! #[double]
//! use outer::inner;
//!
//! #[cfg(test)]
//! mod t {
//! use super::*;
//!
//! #[test]
//! fn test_foo_bar() {
//! let ctx = inner::bar_context();
//! ctx.expect()
//! .returning(|x| i64::from(x + 1));
//! assert_eq!(5, inner::bar(4));
//! }
//! }
//! # fn main() {}
//! ```
//!
//! ### Foreign functions
//!
//! One reason to mock modules is when working with foreign functions. Modules
//! may contain foreign functions, even though structs and traits may not. Like
//! static methods, the expectations are global.
//!
//! ```
//! # use mockall_double::*;
//! mod outer {
//! # use mockall::*;
//! #[automock]
//! pub mod ffi {
//! extern "C" {
//! pub fn foo(x: u32) -> i64;
//! }
//! }
//! }
//!
//! #[double]
//! use outer::ffi;
//!
//! fn do_stuff() -> i64 {
//! unsafe{ ffi::foo(42) }
//! }
//!
//! #[cfg(test)]
//! mod t {
//! use super::*;
//!
//! #[test]
//! fn test_foo() {
//! let ctx = ffi::foo_context();
//! ctx.expect()
//! .returning(|x| i64::from(x + 1));
//! assert_eq!(43, do_stuff());
//! }
//! }
//! # fn main() {}
//! ```
//!
//! ## Debug
//!
//! `#[automock]` will automatically generate `Debug` impls when mocking traits
//! and struct impls. `mock!` will too, if you add a `#[derive(Debug)]`, like
//! this:
//! ```no_run
//! # use mockall::*;
//! mock! {
//! #[derive(Debug)]
//! pub Foo {}
//! }
//! # fn main() {
//! # format!("{:?}", &MockFoo::default());
//! # }
//! ```
//!
//! ## Async Traits
//!
//! Async traits aren't yet (as of 1.47.0) a part of the Rust language. But
//! they're available from the
//! [`async_trait`](https://docs.rs/async-trait/0.1.38/async_trait/) crate.
//! Mockall is compatible with this crate, with two important limitations:
//!
//! * The `#[automock]` attribute must appear _before_ the `#[async_trait]`
//! attribute.
//!
//! * The `#[async_trait]` macro must be imported with its canonical name.
//!
//! ```
//! # use async_trait::async_trait;
//! # use mockall::*;
//! // async_trait works with both #[automock]
//! #[automock]
//! #[async_trait]
//! pub trait Foo {
//! async fn foo(&self) -> u32;
//! }
//! // and mock!
//! mock! {
//! pub Bar {}
//! #[async_trait]
//! impl Foo for Bar {
//! async fn foo(&self) -> u32;
//! }
//! }
//! # fn main() {}
//! ```
//!
//! ## Crate features
//!
//! Mockall has a **nightly** feature. Currently this feature has two
//! effects:
//!
//! * The compiler will produce better error messages.
//!
//! * Expectations for methods whose return type implements `Default` needn't
//! have their return values explicitly set. Instead, they will automatically
//! return the default value.
//!
//! With **nightly** enabled, you can omit the return value like this:
#![cfg_attr(feature = "nightly", doc = "```")]
#![cfg_attr(not(feature = "nightly"), doc = "```should_panic")]
//! # use mockall::*;
//! #[automock]
//! trait Foo {
//! fn foo(&self) -> Vec<u32>;
//! }
//!
//! let mut mock = MockFoo::new();
//! mock.expect_foo();
//! assert!(mock.foo().is_empty());
//! ```
//!
//! ## Examples
//!
//! For additional examples of Mockall in action, including detailed
//! documentation on the autogenerated methods, see
//! [`examples`](examples).
//!
//! [`Predicate`]: trait.Predicate.html
//! [`Sequence`]: Sequence
//! [`cfg-if`]: https://crates.io/crates/cfg-if
//! [`function`]: predicate/fn.function.html
//! [`mock!`]: macro.mock.html
//! [`predicate`]: predicate/index.html
#![cfg_attr(feature = "nightly", feature(specialization))]
// Allow the incomplete_feature warning for specialization. We know it's
// incomplete; that's why it's guarded by the "nightly" feature.
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
#![cfg_attr(feature = "nightly", feature(doc_cfg))]
#![cfg_attr(test, deny(warnings))]
#![warn(missing_docs)]
use downcast::*;
use std::{
any,
fmt::Debug,
marker::PhantomData,
ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
RangeToInclusive},
sync::{
Arc,
atomic::{AtomicUsize, Ordering}
},
};
#[doc(hidden)]
pub use downcast::{Any, Downcast};
#[doc(hidden)]
pub use fragile::Fragile;
/// For mocking static methods
#[doc(hidden)]
pub use lazy_static::lazy_static;
pub use predicates::{
boolean::PredicateBooleanExt,
prelude::{
Predicate, PredicateBoxExt, PredicateFileContentExt, PredicateStrExt,
predicate
}
};
#[doc(hidden)]
pub use predicates_tree::CaseTreeExt;
#[cfg(doc)]
extern crate self as mockall;
#[cfg(doc)]
pub mod examples;
/// Automatically generate mock types for structs and traits.
///
/// This is by far the easiest way to use Mockall. It works on almost all
/// traits, and almost all structs that have a single `impl` block. In either
/// case, it will generate a mock struct whose name is the name of the mocked
/// struct/trait prepended with "Mock". For each method of the original, the
/// mock struct will have a method named `expect_whatever` that allows you to
/// set expectations. There will also be one `checkpoint` method that calls
/// [`checkpoint`] for every single mocked method.
///
/// # Examples
///
/// The simplest use case is mocking a no-frills trait
/// ```
/// # use mockall_derive::*;
/// #[automock]
/// pub trait Foo {
/// fn foo(&self, key: i16);
/// }
///
/// let mock = MockFoo::new();
/// ```
///
/// Mocking a structure:
/// ```
/// # use mockall_derive::*;
/// struct Foo {}
/// #[automock]
/// impl Foo {
/// fn foo(&self) -> u32 {
/// // ...
/// # unimplemented!()
/// }
/// }
/// ```
///
/// You can also mock a trait impl on a struct:
/// ```
/// # use mockall_derive::*;
/// pub trait Foo {
/// fn foo(&self, key: i16);
/// }
/// struct Bar{}
/// #[automock]
/// impl Foo for Bar {
/// fn foo(&self, key: i16){
/// // ...
/// # unimplemented!()
/// }
/// }
///
/// let mock = MockBar::new();
/// ```
///
/// Mocking a trait with associated types requires adding a metaitem to the
/// attribute:
/// ```
/// # use mockall_derive::*;
/// #[automock(type Item=u32;)]
/// trait Foo {
/// type Item;
/// fn foo(&self) -> Self::Item;
/// }
/// ```
///
/// It can mock a module full of functions. In this case, the mock functions
/// will be found in a module whose name is prepended with `mock_`.
///
/// ```
/// # use mockall_derive::*;
/// #[automock]
/// mod mymod {
/// pub fn foo() -> u32 {
/// // ...
/// # unimplemented!()
/// }
/// }
/// ```
/// Finally, `#[automock]` can also mock foreign functions. This works just
/// like mocking a module.
///
/// ```
/// # use mockall_derive::*;
/// #[automock]
/// mod ffi {
/// extern "C" {
/// pub fn foo() -> u32;
/// }
/// }
/// ```
///
/// [`checkpoint`]: ../mockall/index.html#checkpoints
///
/// # Limitations
///
/// `#[automock]` can't handle everything. There are some cases where
/// you will need to use [`mock`] instead:
/// * Mocking a struct that has multiple `impl` blocks, including
/// structs that implement traits.
/// * Mocking a struct or trait defined in another crate.
/// * Mocking a trait with trait bounds.
/// * If the autogenerated "MockFoo" name isn't acceptable, and you want
/// to choose your own name for the mock structure.
pub use mockall_derive::automock;
/// Decorates a method or function to tell Mockall to treat its generic arguments
/// as trait objects when creating expectations.
///
/// This allows users to use non-`'static` generic parameters, which otherwise
/// can't be mocked. The downsides of using this attribute are:
///
/// * Mockall can't tell if a parameter isn't `'static`, so you must annotate
/// such methods with the `#[mockall::concretize]` attribute.
/// * Generic methods will share expectations for all argument types. That is,
/// you won't be able to do `my_mock.expect_foo::<i32>(...)`.
/// * It can't be used on methods with a closure argument (though this may be
/// fixable).
/// * Concretized methods' expectations may only be matched with `.withf` or
/// `.withf_st`, not `.with`.
/// * It only works for parameters that can be turned into a trait object.
/// (may be fixable).
/// * Mockall needs to know how to turn the function argument into a trait
/// object. Given a generic parameter `T`, currently supported patterns are:
/// - `T`
/// - `&T`
/// - `&mut T`
/// - `&[T]`
///
/// # Examples
/// ```
/// # use std::path::Path;
/// # use mockall::{automock, concretize};
/// #[automock]
/// trait Foo {
/// #[mockall::concretize]
/// fn foo<P: AsRef<Path>>(&self, p: P);
/// }
///
/// # fn main() {
/// let mut mock = MockFoo::new();
/// mock.expect_foo()
/// .withf(|p| p.as_ref() == Path::new("/tmp"))
/// .return_const(());
/// mock.foo(Path::new("/tmp"));
/// # }
/// ```
///
/// NB: This attribute must be imported with its canonical name. It won't work
/// otherwise!
/// ```compile_fail
/// use mockall::concretize as something_else;
/// #[mockall::automock]
/// trait Foo {
/// #[something_else]
/// fn foo<T>(&self, t: T);
/// }
/// ```
pub use mockall_derive::concretize;
/// Manually mock a structure.
///
/// Sometimes `automock` can't be used. In those cases you can use `mock!`,
/// which basically involves repeating the struct's or trait's definitions.
///
/// The format is:
///
/// * Optional visibility specifier
/// * Real structure name and generics fields
/// * 0 or more methods of the structure, written without bodies, enclosed in a
/// {} block
/// * 0 or more impl blocks implementing traits on the structure, also without
/// bodies.
///
/// # Examples
///
/// Mock a trait. This is the simplest use case.
/// ```
/// # use mockall_derive::mock;
/// trait Foo {
/// fn foo(&self, x: u32);
/// }
/// mock!{
/// pub MyStruct<T: Clone + 'static> {
/// fn bar(&self) -> u8;
/// }
/// impl<T: Clone + 'static> Foo for MyStruct<T> {
/// fn foo(&self, x: u32);
/// }
/// }
/// # fn main() {}
/// ```
/// Mocking an unsupported `#[derive(X)]` attribute, e.g. `Clone`, is
/// similar.
/// ```
/// # use mockall_derive::mock;
/// #[derive(Clone)]
/// struct MyStruct;
///
/// mock!{
/// pub MyStruct {
/// fn bar(&self);
/// }
/// impl Clone for MyStruct {
/// fn clone(&self) -> Self;
/// }
/// }
/// # fn main() {}
/// ```
///
/// When mocking a generic struct's implementation of a generic trait, use the
/// same name for their generic parameters. For example, if you wanted to mock
/// `Rc`, do
/// ```
/// # use mockall_derive::mock;
/// mock!{
/// pub Rc<T: 'static> {}
/// impl<T: 'static> AsRef<T> for Rc<T> {
/// fn as_ref(&self) -> &T;
/// }
/// }
/// # fn main() {}
/// ```
/// *not*
/// ```compile_fail
/// # use mockall_derive::mock;
/// mock!{
/// pub Rc<Q: 'static> {}
/// impl<T: 'static> AsRef<T> for Rc<T> {
/// fn as_ref(&self) -> &T;
/// }
/// }
/// # fn main() {}
/// ```
/// Associated types can easily be mocked by specifying a concrete type in the
/// `mock!{}` invocation.
/// ```
/// # use mockall_derive::mock;
/// mock!{
/// MyIter {}
/// impl Iterator for MyIter {
/// type Item=u32;
///
/// fn next(&mut self) -> Option<<Self as Iterator>::Item>;
/// }
/// }
/// # fn main() {}
/// ```
pub use mockall_derive::mock;
#[doc(hidden)]
pub trait AnyExpectations : Any + Send + Sync {}
downcast!(dyn AnyExpectations);
#[doc(hidden)]
pub trait ReturnDefault<O> {
fn maybe_return_default() -> Option<O>;
fn return_default() -> Result<O, &'static str>;
}
#[derive(Default)]
#[doc(hidden)]
pub struct DefaultReturner<O>(PhantomData<O>);
::cfg_if::cfg_if! {
if #[cfg(feature = "nightly")] {
impl<O> ReturnDefault<O> for DefaultReturner<O> {
default fn maybe_return_default() -> Option<O> {
None
}
default fn return_default() -> Result<O, &'static str> {
Err("Can only return default values for types that impl std::Default")
}
}
impl<O: Default> ReturnDefault<O> for DefaultReturner<O> {
fn maybe_return_default() -> Option<O> {
Some(O::default())
}
fn return_default() -> Result<O, &'static str> {
Ok(O::default())
}
}
} else {
impl<O> ReturnDefault<O> for DefaultReturner<O> {
fn maybe_return_default() -> Option<O> {
None
}
fn return_default() -> Result<O, &'static str> {
Err("Returning default values requires the \"nightly\" feature")
}
}
}
}
// Wrapper type to allow for better expectation messages for any type.
// Will first try Debug, otherwise will print '?'
#[doc(hidden)]
pub struct ArgPrinter<'a, T>(pub &'a T);
#[doc(hidden)]
pub struct DebugPrint<'a, T: Debug>(pub &'a T);
impl<'a, T> Debug for DebugPrint<'a, T> where T: Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(self.0, f)
}
}
#[doc(hidden)]
pub trait ViaDebug<T> where T: Debug { fn debug_string(&self) -> DebugPrint<'_, T>; }
impl<'a, T: Debug> ViaDebug<T> for &ArgPrinter<'a, T> {
fn debug_string(&self) -> DebugPrint<'a, T> {
DebugPrint(self.0)
}
}
#[doc(hidden)]
pub struct NothingPrint;
impl Debug for NothingPrint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "?")
}
}
#[doc(hidden)]
pub trait ViaNothing { fn debug_string(&self) -> NothingPrint; }
impl<'a, T> ViaNothing for ArgPrinter<'a, T> {
fn debug_string(&self) -> NothingPrint {
NothingPrint
}
}
// Though it's not entirely correct, we treat usize::max_value() as
// approximately infinity.
#[derive(Debug)]
#[doc(hidden)]
pub struct TimesRange(Range<usize>);
impl Default for TimesRange {
fn default() -> TimesRange {
// By default, allow any number of calls
TimesRange(0..usize::max_value())
}
}
impl From<usize> for TimesRange {
fn from(n: usize) -> TimesRange {
TimesRange(n..(n+1))
}
}
impl From<Range<usize>> for TimesRange {
fn from(r: Range<usize>) -> TimesRange {
assert!(r.end > r.start, "Backwards range");
TimesRange(r)
}
}
impl From<RangeFrom<usize>> for TimesRange {
fn from(r: RangeFrom<usize>) -> TimesRange {
TimesRange(r.start..usize::max_value())
}
}
impl From<RangeFull> for TimesRange {
fn from(_: RangeFull) -> TimesRange {
TimesRange(0..usize::max_value())
}
}
impl From<RangeInclusive<usize>> for TimesRange {
fn from(r: RangeInclusive<usize>) -> TimesRange {
assert!(r.end() >= r.start(), "Backwards range");
TimesRange(*r.start()..*r.end() + 1)
}
}
impl From<RangeTo<usize>> for TimesRange {
fn from(r: RangeTo<usize>) -> TimesRange {
TimesRange(0..r.end)
}
}
impl From<RangeToInclusive<usize>> for TimesRange {
fn from(r: RangeToInclusive<usize>) -> TimesRange {
TimesRange(0..r.end + 1)
}
}
#[derive(PartialEq)]
#[doc(hidden)]
pub enum ExpectedCalls {
Satisfied,
TooMany,
TooFew,
}
#[derive(Debug, Default)]
#[doc(hidden)]
pub struct Times{
/// How many times has the expectation already been called?
count: AtomicUsize,
range: TimesRange
}
#[doc(hidden)]
impl Times {
pub fn call(&self) -> Result<(), String> {
let count = self.count.fetch_add(1, Ordering::Relaxed) + 1;
if count >= self.range.0.end {
if self.range.0.end == 1 {
Err("should not have been called".to_owned())
} else {
Err(format!(
"called {} times which is more than the expected {}",
count,
self.range.0.end - 1
))
}
} else {
Ok(())
}
}
pub fn any(&mut self) {
self.range.0 = 0..usize::max_value();
}
/// Return how many times this expectation has been called
pub fn count(&self) -> usize {
self.count.load(Ordering::Relaxed)
}
/// Has this expectation already been called the maximum allowed number of
/// times?
pub fn is_done(&self) -> bool {
self.count.load(Ordering::Relaxed) >= self.range.0.end - 1
}
/// Is it required that this expectation be called an exact number of times,
/// or may it be satisfied by a range of call counts?
pub fn is_exact(&self) -> bool {
(self.range.0.end - self.range.0.start) == 1
}
/// Has this expectation already been called the expected number of times?
/// If not, was it too many or too few?
pub fn is_satisfied(&self) -> ExpectedCalls {
let satisfied_lower_bound = self.count.load(Ordering::Relaxed) >= self.range.0.start;
let satisfied_upper_bound = self.count.load(Ordering::Relaxed) < self.range.0.end;
if satisfied_lower_bound && satisfied_upper_bound {
ExpectedCalls::Satisfied
} else if satisfied_lower_bound {
ExpectedCalls::TooMany
} else {
ExpectedCalls::TooFew
}
}
/// The maximum number of times that this expectation must be called
pub fn maximum(&self) -> usize {
self.range.0.end - 1
}
/// The minimum number of times that this expectation must be called
pub fn minimum(&self) -> usize {
self.range.0.start
}
// https://github.com/rust-lang/rust-clippy/issues/3307
#[allow(clippy::range_plus_one)]
pub fn n(&mut self, n: usize) {
self.range.0 = n..(n+1);
}
pub fn never(&mut self) {
self.range.0 = 0..1;
}
pub fn range(&mut self, range: Range<usize>) {
assert!(range.end > range.start, "Backwards range");
self.range.0 = range;
}
pub fn times<T: Into<TimesRange>>(&mut self, t: T) {
self.range = t.into();
}
}
/// Non-generic keys to `GenericExpectation` internal storage
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Key(any::TypeId);
#[doc(hidden)]
impl Key {
pub fn new<T: 'static + ?Sized>() -> Self {
Key(any::TypeId::of::<T>())
}
}
#[doc(hidden)]
pub struct SeqHandle {
inner: Arc<SeqInner>,
seq: usize
}
impl SeqHandle {
/// Tell the Sequence that this expectation has been fully satisfied
pub fn satisfy(&self) {
self.inner.satisfy(self.seq);
}
/// Verify that this handle was called in the correct order
pub fn verify(&self, desc: &str) {
self.inner.verify(self.seq, desc);
}
}
#[derive(Default)]
struct SeqInner {
satisfaction_level: AtomicUsize,
}
impl SeqInner {
/// Record the call identified by `seq` as fully satisfied.
fn satisfy(&self, seq: usize) {
let old_sl = self.satisfaction_level.fetch_add(1, Ordering::Relaxed);
assert_eq!(old_sl, seq, "Method sequence violation. Was an already-satisfied method called another time?");
}
/// Verify that the call identified by `seq` was called in the correct order
fn verify(&self, seq: usize, desc: &str) {
assert_eq!(seq, self.satisfaction_level.load(Ordering::Relaxed),
"{desc}: Method sequence violation")
}
}
/// Used to enforce that mock calls must happen in the sequence specified.
///
/// Each expectation must expect to be called a fixed number of times. Once
/// satisfied, the next expectation in the sequence will expect to be called.
///
/// # Examples
/// ```
/// # use mockall::*;
/// #[automock]
/// trait Foo {
/// fn foo(&self);
/// fn bar(&self) -> u32;
/// }
/// let mut seq = Sequence::new();
///
/// let mut mock0 = MockFoo::new();
/// let mut mock1 = MockFoo::new();
///
/// mock0.expect_foo()
/// .times(1)
/// .returning(|| ())
/// .in_sequence(&mut seq);
///
/// mock1.expect_bar()
/// .times(1)
/// .returning(|| 42)
/// .in_sequence(&mut seq);
///
/// mock0.foo();
/// mock1.bar();
/// ```
///
/// It is an error to add an expectation to a `Sequence` if its call count is
/// unspecified.
/// ```should_panic(expected = "with an exact call count")
/// # use mockall::*;
/// #[automock]
/// trait Foo {
/// fn foo(&self);
/// }
/// let mut seq = Sequence::new();
///
/// let mut mock = MockFoo::new();
/// mock.expect_foo()
/// .returning(|| ())
/// .in_sequence(&mut seq); // panics!
/// ```
#[derive(Default)]
pub struct Sequence {
inner: Arc<SeqInner>,
next_seq: usize,
}
impl Sequence {
/// Create a new empty [`Sequence`]
pub fn new() -> Self {
Self::default()
}
/// Not for public consumption, but it must be public so the generated code
/// can call it.
#[doc(hidden)]
pub fn next_handle(&mut self) -> SeqHandle {
let handle = SeqHandle{inner: self.inner.clone(), seq: self.next_seq};
self.next_seq += 1;
handle
}
}