65

I have 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.

#[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() {
        // for some reason, test cannot be 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 a Future type
        // Future type 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);
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
DennyHiu
  • 4,861
  • 8
  • 48
  • 80
  • 8
    use `#[tokio::test]` instead of `#[test]` for async tests. – Ivan C Apr 17 '21 at 00:54
  • it solves my problem. Just add `#[tokio::test]` and suddenly my test function can accept `await`. If you use `actix-web` you can add `actix_rt` into Cargo.toml and `#[actix_rt::test]` before the test function – DennyHiu Apr 17 '21 at 01:06

1 Answers1

91

Just replace #[test] with #[tokio::test] before any test function. If you use actix-web you can add actix_rt into Cargo.toml and #[actix_rt::test] before the test function

#[tokio::test]
async fn test_something_async() {
    let DB = setup().await; // <- 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 a Future type 
    // Future type 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).await;
}
ADM-IT
  • 3,719
  • 1
  • 25
  • 26
DennyHiu
  • 4,861
  • 8
  • 48
  • 80