Ideally I would also be able to pass the server to the test function which I've been able to accomplish although it complains about thread problems.
The actual test closure still needs to be async.
pub async fn run_test<T>(test: T) -> ()
where
T: FnOnce() -> () + panic::UnwindSafe,
{
setup().await;
// let srv = super::server().await;
let text = "text";
let result = panic::catch_unwind(|| test());
teardown().await;
assert!(result.is_ok())
}
This is the test which always complains of return opaque type and then If I switch T: FnOnce() -> () + panic::UnwindSafe,. To any sort of future it complains about not knowing the size.
#[actix_rt::test]
async fn test_index_get() {
run_test(|| {
{
let srv = super::server().await;
// let req = TestRequest::with_header("content-type", "text/plain").to_request();
// let res = read_response(&mut srv, req).await;
// assert_eq!(res, "Hello World".as_bytes());
assert!(true);
}
})
.await;
}
Trying to use Future as the return type directly doesn't work because Future is a trait, so if you try to use it as a type, you actually get the trait object type dyn Future, which is not the same as the trait, and is a specific concrete type that any future can be turned into. Since any future can be turned into a trait object dyn Future, it has no known size and must be boxed. To use the trait object, you would write it like this:
but I recommend using generics, as the above doesn't work with an async function directly. An async function returns a specific concrete type that implements future, which is different from the trait object type, so you must explicitly add a Box::pin(your_future) at the end to return the right type.
Regarding the catching of unwind thing, you can't use the standard catch unwind on a future, and you need this extension method to handle it.