Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test async functions in rust?

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);
    }
}
like image 704
DennyHiu Avatar asked Apr 16 '21 22:04

DennyHiu


People also ask

Does Rust support asynchronous?

The async/await syntax is supported directly by the Rust compiler. Many utility types, macros and functions are provided by the futures crate. They can be used in any async Rust application. Execution of async code, IO and task spawning are provided by "async runtimes", such as Tokio and async-std.

What is async FN in Rust?

async / . await is Rust's built-in tool for writing asynchronous functions that look like synchronous code. async transforms a block of code into a state machine that implements a trait called Future .

Why we use async and await in protractor?

We need wrap our asynchronous function with “async”. We can add “await” keyword to each operation that we want our program to wait for. Note: Never forget to add “await” keyword in an async function, it may bring some unexpected problem (e.g. your test might fail silently and always be reported as passed).


1 Answers

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;
}
like image 54
DennyHiu Avatar answered Nov 01 '22 09:11

DennyHiu