I am trying to unit-test a request handler that uses middleware to pass data into it. Before implementing the middleware tests were fairly straightforward, I could use web::Data::new(data)
to pass test data into the handler. However, now that the data is wrapped in web::ReqData
I’m having trouble figuring out how to pass in data for testing.
example:
pub async fn handler(
some_data: web::Data<SomeDataType>,
req_data: web::ReqData<ReqestDataType>
) -> HttpResponse {
// some code
}
#[actix_rt::test]
async fn test_fn() {
let resp = handler(
web::Data::new(someData),
// what can I put here?
).await;
assert_eq!(resp.status(), status_code::OKAY);
}
“Request-local data is arbitrary data attached to an individual request, usually by middleware. It can be set via extensions_mut on HttpRequest or ServiceRequest”
ReqData<T>
can be extracted from the HttpRequest using extract
method of ReqData<T>
.
Refer
How to create test HttpRequest is documented here
With this information we create a test HttpRequest then set the ReqData using the extensions_mut
method, then extract it using ReqData::extract
method.
Example:
use actix_web::{HttpResponse, web};
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct User {
id: u32,
name: String,
}
pub async fn handler(
some_data: web::Data<String>,
req_data: web::ReqData<User>
) -> HttpResponse {
// some code
println!("{:?}", some_data);
println!("{:?}", req_data);
HttpResponse::Ok().finish()
}
#[cfg(test)]
mod tests {
use actix_web::{test, FromRequest, HttpMessage, web::ReqData};
use super::*;
#[actix_rt::test]
async fn test_fn() {
let http_request = test::TestRequest::default().to_http_request();
http_request.extensions_mut().insert(User{id: 1, name: "User1".to_string()});
let _ = handler(
web::Data::new("Dummy data".to_string()),
ReqData::extract(&http_request).await.unwrap()
).await;
}
}