How can I mock/create ReqData for testing an actix web request handler?

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;
    }
}

Leave a Comment