unit-testingrustrust-actix

Getting error "expected function" when trying to call function from a unit test


I'm trying to write a simple unit test case for an Actix web function, however I'm getting an error when trying to call the function from the test function. The error I'm getting is: E0618: expected function, found <my function name>

I've tried calling it exactly the way advised on Actix website.

Here's a code sample:

use actix_web::{get, web, Responder, Result};
use serde::Serialize;

#[derive(Serialize, Debug)]
struct PingResponse {
    status: String,
}

#[get("/ping")]
async fn health_check() -> Result<impl Responder> {
    //web::Json<PingResponse> {
    let resp = PingResponse {
        status: "alive".to_string(),
    };

    Ok(web::Json(resp))
}

#[cfg(test)]
mod tests {
    use super::*;
    use actix_web::test;

    #[actix_web::test]
    async fn test_ping_ok() {
        let req = test::TestRequest::default().to_http_request();

        // E0618 expected function, found `health::health_check`
        let resp = health_check(req).await;

        // E0618: expected function, found `health_check`
        // let resp = crate::apis::health::health_check(req);

        assert_eq!(resp.status(), "alive".to_string());
    }
}

I've tried calling the health_check function by just using the function name as well as by using the fully qualified function name.

The diagnostic message is:

error[E0618]: expected function, found `apis::health::health_check`
  --> src/apis/health.rs:29:20
   |
9  | #[get("/ping")]
   | --------------- `apis::health::health_check` defined here
...
29 |         let resp = health_check(req).await;
   |                    ^^^^^^^^^^^^-----
   |                    |
   |                    call expression requires function

Solution

  • I can see that the function isn't returning what I think it was, but rather, a struct. I have found a couple solutions:

    1. Remove the #[get("/ping")] attribute and do the routing from the http server setup. This allows me to call the function normally from the unit test.

    2. Use test::TestRequest::get() and then do app.call(req) to make the call generically. This way I can leave the routing on the function.