Test async function?

I had an async function that I need to test. this function uses a mongodb::Database object to run. So I initialize the connection in the setup() function and use tokio_test::block_on() to wrap the await expression inside. Here's my code:

#[cfg(test)]
mod tests {

    use mongodb::{options::ClientOptions, Client};
    use tokio_test;

    async fn setup() -> mongodb::Database {
        tokio_test::block_on(async {
            let client_uri = "mongodb://127.0.0.1:27017";
            let options = ClientOptions::parse(&client_uri).await;
            let client_result = Client::with_options(options.unwrap());
            let client = client_result.unwrap();
            client.database("my_database")
        })
    }

    #[test]
    fn test_something_async() {
        let DB = setup(); // <- the DB is impl std::future::Future type

        // the DB variable will be used to run another
        // async function named "some_async_func"
        // but it doesn't work since DB is Future that need await keyword
        // but if I use await-async keywords here, it complains
        // error: async functions cannot be used for tests
        // so what to do here ?
        some_async_func(DB);
    }
}

Without having looked at the documentation: I don't think you need async for your setup function as block_on already wars for the future to finish.

What's it mean ?

tokio::block_on is not async itself, so the function enclosing it don't have to be async, either.

Similar to the #[tokio::main], you can use #[tokio::test] to test async functions.

https://docs.rs/tokio/1.5.0/tokio/attr.test.html

And to block_on() within the async context is bad. It can either crash, deadlock, or reduce the server's throughput at best.

1 Like

I ended up using this

It means it setup should look like this:

 fn setup() -> mongodb::Database {
        tokio_test::block_on(async {
            let client_uri = "mongodb://127.0.0.1:27017";
            let options = ClientOptions::parse(&client_uri).await;
            let client_result = Client::with_options(options.unwrap());
            let client = client_result.unwrap();
            client.database("my_database")
        })
    }

In reality it should probably look like this:

async fn setup() -> mongodb::Database {
    let client_uri = "mongodb://127.0.0.1:27017";
    let options = ClientOptions::parse(&client_uri).await;
    let client_result = Client::with_options(options.unwrap());
    let client = client_result.unwrap();
    client.database("my_database")
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.