asomers / mockall

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

No `Mock` implementation of Trait being created #460

Closed RoloEdits closed 1 year ago

RoloEdits commented 1 year ago

Trying to figure out why a Mock prefixed version of the trait isn't showing up as existing. The example I based off of was the README. I'm sure I'm missing something obvious, but can't seem to find out what.

[dev-dependencies]
mockall = "0.11.3"
#[cfg(test)]
use mockall::{automock, mock, predicate::*};

#[cfg_attr(test, automock)]
#[async_trait]
pub trait ClientTrait: Debug {
    fn new() -> Result<ClientAsync, reqwest::Error>;

    fn with_session(session: &str) -> Result<ClientAsync, reqwest::Error>;

    async fn get(&self, url: &str) -> Result<String, reqwest::Error>;

    async fn get_json(&self, url: &str) -> Result<String, reqwest::Error>;
}

#[derive(Debug)]
pub struct ClientAsync {
    client: reqwest::Client,
    session: Option<String>,
}

#[async_trait]
impl ClientTrait for ClientAsync {
    fn new() -> Result<ClientAsync, reqwest::Error>{...}

    fn with_session(session: &str) -> Result<ClientAsync, reqwest::Error> {...}

    async fn get(&self, url: &str) -> Result<String, reqwest::Error> {...}

    async fn get_json(&self, url: &str) -> Result<String, reqwest::Error> {...}
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test() {
        // No `Mock` prefixed version of the trait exists. It doesn't show up in auto-completion,
        // nor is there a prompt to import.
        let mut mock = MockClientTrait::new();
    }
}
asomers commented 1 year ago

This is a problem with your editor, not Mockall. Most likely the editor expands the code in production configuration, not test configuration. What happens when you build?

RoloEdits commented 1 year ago

Ok, I managed to get it working now. Seems there was an issue with using ::new() and switching to ::default() gave me a Mock object. I guess its a name conflict, already having a ::new() function on the trait. If this is the case I think it should be in some kind of documentation. Though what happens if you also have a default implementation? And both function names are taken?

The confounding issue was the fact that the Rust IntelliJ plugin doesn't seem to have any hints or highlighting for the object. Opening in VS Code with rust-analyzer shows the correct hints and highlighting.

asomers commented 1 year ago

In fact it is already mentioned in the documentation. https://docs.rs/mockall/latest/mockall/#static-methods . And it isn't likely to be a problem if you already have a default method, because who would ever use that name for a method outside of the Default trait? And even if they do, you'll still be able to do <MyMock as Default>::default().