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);
}
}
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.
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 .
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).
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With