nrxus / faux

Struct mocking library for Rust
https://nrxus.github.io/faux/
MIT License
411 stars 14 forks source link

`faux::methods` bug on recognizing types #51

Closed lauti7 closed 11 months ago

lauti7 commented 1 year ago

Hi! Ive been implementing faux to mock some structs but I'm stuck in an error that i can not work it out. Hope you can help me out with this. The issue is that the compiler is throwing an error due to the return type. The error is below:

the return type refers to the mocked struct in a way that faux cannot handle. Split this function into animplblock not marked by #[faux::methods]. If you believe this is a mistake or it's a case that should be handled by faux please file an issue

Here below is the code. The issue is on Redis::run function but this function doesn't return a type that refers to the mocked struct, it just returns ():

#[cfg_attr(test, faux::create)]
#[derive(Clone)]
pub struct Redis {
    redis_host: String,
    pub pool: Option<Pool>,
}

impl std::fmt::Debug for Redis {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Redis")
            .field("redis_host", &self.redis_host)
            .field("pool", &self.pool.is_some())
            .finish()
    }
}

#[cfg_attr(test, faux::methods)]
impl Redis {
    pub fn new(config: &RedisConfig) -> Self {
        Self {
            redis_host: config.host.clone(),
            pool: None,
        }
    }
    async fn stop(&mut self) {
        self.pool.as_mut().unwrap().close()
    }

    async fn run(&mut self) -> Result<(), RedisError> {
        if self.pool.is_none() {
            let url = format!("redis://{}", self.redis_host);
            log::debug!("Redis URL: {}", url);

            match Config::from_url(url).create_pool(Some(Runtime::Tokio1)) {
                Ok(pool) => {
                    self.pool = Some(pool);
                }
                Err(err) => {
                    log::debug!("Error on connecting to redis: {:?}", err);
                    panic!("Unable to connect to redis {:?}", err)
                }
            };

            Ok("".to_string())
        } else {
            log::debug!("Redis Connection is already set.");
            Ok("".to_string())
        }
    }

    async fn get_async_connection(&mut self) -> Option<Connection> {
        match self.pool.as_mut().unwrap().get().await {
            Ok(connection) => Some(connection),
            Err(err) => {
                log::error!("Error getting connection from redis: {:?}", err);
                None
            }
        }
    }
}

That's all, hope you can help me.

nrxus commented 1 year ago

šŸ¤¦šŸ¾ this is due to me doing a very silly check when trying to check if the returned type includes the mocked struct: https://github.com/nrxus/faux/blob/709e053cc151bd8fa82578f1b28497ed26dbb1e1/faux_macros/src/methods/morphed.rs#L255-L262

This checks if any part of the return type includes the word "Self" or the name as the struct. In this case the return type Result<(), RedisError> includes the name of the struct Redis so faux gets confused and thinks that this return type is special and then eventually breaks when trying to figure out how to convert into the actual return type.

I will try to get a fix out in the coming days for this but in the meantime a type alias somewhere in the module should fix this.

type MyError = RedisError

and then in the function signature -> Result<(), MyError>.

schneidersteve commented 1 year ago

Same behavior with an -> Option<...> return type

lauti7 commented 1 year ago

@nrxus Great! Thx for the quick response. I've implemented another workaround and combined two methods in one, but your workaround is much better.

I don't close the issue so that you can close it when submitting the fix! Thx again!

schneidersteve commented 1 year ago

@nrxus Any news regarding the fix?

nrxus commented 1 year ago

@schneidersteve I've unfortunately been too swamped between work and life to take a stab at a fix yet. I am hoping to come back to faux soon since there are quite a few improvements I want to make including this fix. In the meantime though, I am always open for PRs šŸ˜„

nrxus commented 11 months ago

Fixed in https://github.com/nrxus/faux/commit/6aa254acc217fc73feb19630a47c3f16e1efd824 which I just released as v0.1.10.

Hopefully this addresses the issues but please let me know if something is still wonky.