use mockiato::mockable; use std::fmt::{self, Display}; trait Foo { type Output; } #[mockable] trait Greeter where T: Display, V: Foo, V::Output: Display, { fn generic_param_as_argument(&self, name: T) -> String; fn associated_type(&self, name: V::Output) -> String; fn generic_param_wrapped_in_container(&self, names: Vec) -> String; fn generic_param_as_return_value(&self, name: String) -> T; } #[derive(PartialEq, Eq)] struct Name { name: String, } impl Name { fn new(name: S) -> Self where S: Into, { Self { name: name.into() } } } impl Display for Name { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "{}", self.name) } } impl Foo for String { type Output = String; } #[test] fn trait_with_generic_type_argument_can_be_mocked() { let mut mock: GreeterMock = GreeterMock::new(); const EXPECTED_NUMBER_OF_CALLS: u64 = 2; mock.expect_generic_param_as_argument(|arg| arg.partial_eq(Name::new("Foo"))) .times(EXPECTED_NUMBER_OF_CALLS) .returns(String::from("Hello Foo")); for _ in 0..EXPECTED_NUMBER_OF_CALLS { assert_eq!( "Hello Foo", mock.generic_param_as_argument(Name::new("Foo")) ); } }