#[macro_use] extern crate double; // Traits which only return types that implement `Default`. trait Calculator: Clone { fn multiply(&self, x: i32, y: i32) -> i32; } trait BalanceSheet: Clone { fn profit(&self, revenue: u32, costs: u32) -> i32; fn loss(&self, revenue: u32, costs: u32) -> i32; } trait Greeter: Clone { fn greet>(&mut self, name: S); } mock_trait!(EmptyMock); mock_trait!( MockCalculator, multiply(i32, i32) -> i32); impl Calculator for MockCalculator { mock_method!(multiply(&self, x: i32, y: i32) -> i32); } mock_trait!( MockBalanceSheet, profit(u32, u32) -> i32, loss(u32, u32) -> i32); impl BalanceSheet for MockBalanceSheet { mock_method!(profit(&self, revenue: u32, costs: u32) -> i32); mock_method!(loss(&self, revenue: u32, costs: u32) -> i32); } mock_trait!( MockGreeter, greet(String) -> ()); impl Greeter for MockGreeter { mock_method!(greet<(S: AsRef)>(&mut self, name: S), self, { self.greet.call(name.as_ref().to_string()); }); } // Traits which return types that do not implement `Default`. #[derive(Debug, Clone, PartialEq)] pub struct User { name: String } pub trait UserStore { fn get_user(&self, id: i32) -> Result; fn delete_user(&self, id: i32) -> Result<(), String>; } mock_trait_no_default!( MockUserStore, get_user(i32) -> Result, delete_user(i32) -> Result<(), String>); impl UserStore for MockUserStore { mock_method!(get_user(&self, id: i32) -> Result); mock_method!(delete_user(&self, id: i32) -> Result<(), String>); } fn main() { // Test individual return values let mock = MockBalanceSheet::default(); mock.profit.return_value(42); mock.profit.return_value_for((0, 0), 9001); let value = mock.profit(10, 20); assert_eq!(42, value); mock.profit.has_calls_exactly_in_order(vec!((10, 20))); let value = mock.profit(0, 0); assert_eq!(9001, value); mock.profit.has_calls_exactly_in_order(vec!((10, 20), (0, 0))); // Test sequence of return values mock.profit.return_values(vec!(1, 2, 3)); assert_eq!(1, mock.profit.call((1, 2))); assert_eq!(2, mock.profit.call((2, 4))); assert_eq!(3, mock.profit.call((3, 6))); assert_eq!(42, mock.profit.call((4, 8))); // Test using mocks that do not implement the `Default` trait. // One must manually specify the default values for all methods in the // mocked trait. let store = MockUserStore::new( Err("cannot get, no user with given ID".to_owned()), Err("cannot delete, no user with given ID".to_owned())); store.get_user.return_value_for( 42, Ok(User{ name: "Donald".to_owned() })); assert_eq!( Err("cannot get, no user with given ID".to_owned()), store.get_user(10)); assert_eq!( Ok(User{ name: "Donald".to_owned() }), store.get_user(42)); store.delete_user.return_value_for(42, Ok(())); assert_eq!( Err("cannot delete, no user with given ID".to_owned()), store.delete_user(10)); assert_eq!(Ok(()), store.delete_user(42)); }