asomers / mockall

A powerful mock object library for Rust
Apache License 2.0
1.5k stars 62 forks source link

#[automock] wont' respect trait's supertraits #468

Closed jaysonsantos closed 1 year ago

jaysonsantos commented 1 year ago

Hi there, while trying to implement automock I stumbled on an issue, given this sample trait:

#[async_trait]
#[cfg_attr(test, automock)]
pub trait Authenticate: Clone + Send + Sync + 'static {
    async fn authenticate(&self, req: Request<Body>) -> Result<Request<Body>, Status>;
}

The code won't compile because the generated struct does not implement clone:

error[E0277]: the trait bound `MockAuthenticate: Clone` is not satisfied
  --> orchestrator/src/auth.rs:14:11
   |
14 | pub trait Authenticate: Clone + Send + Sync + 'static {
   |           ^^^^^^^^^^^^ the trait `Clone` is not implemented for `MockAuthenticate`
   |
note: required by a bound in `Authenticate`
  --> orchestrator/src/auth.rs:14:25
   |
14 | pub trait Authenticate: Clone + Send + Sync + 'static {
   |                         ^^^^^ required by this bound in `Authenticate`

the generated struct is:

    #[allow(non_camel_case_types)]
    #[allow(non_snake_case)]
    #[allow(missing_docs)]
    pub struct MockAuthenticate {
        Authenticate_expectations: MockAuthenticate_Authenticate,
    }

I wonder if it would be worth it to make Authenticate_expectations something like Arc<Mutex<MockAuthenticate_Authenticate>> so it can be clonable and still hold a central reference for all expectations?

asomers commented 1 year ago

Nope. Mockall cannot derive Clone. You'll have to mock it. And #[automock] can't handle type bounds. You'll have to use mock! instead. See https://github.com/asomers/mockall/blob/master/mockall/tests/mock_clone.rs . Also, if you want to automock an async_trait, you must be the #[automock] attribute first, and #[async_trait] second. See https://github.com/asomers/mockall/blob/master/mockall/tests/mock_async_trait.rs for an example of using mock! with #[async_trait].

jaysonsantos commented 1 year ago

Thanks for the clarification @asomers !