I'm not able to write a test for the lamda_http query_string_parameters

use lambda_http::{
    handler,
    lambda::{self, Context},
    IntoResponse, Request, RequestExt, Response,
};
use serde_json::json;
use log::{info};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[tokio::main]
async fn main() -> Result<(), Error> {
    env_logger::Builder::new()
        .target(env_logger::Target::Stdout)
        .init();

    lambda::run(handler(func)).await?;
    Ok(())
}

async fn func(event: Request, _: Context) -> Result<impl IntoResponse, Error> {

    info!("Test log info message");
    println!("Event is: {:?}", event);
    println!("Event headers: {:?}", event.headers());
    println!("query_string_parameters is: {:?}", event.query_string_parameters());

    Ok(match event.query_string_parameters().get("first_name") {
        Some(first_name) => json!({ "first_name": first_name }).into_response(),
        _ => Response::builder()
            .status(400)
            .body("Empty first name".into())
            .expect("failed to render response"),
    })
}

#[cfg(test)]
mod tests {
    use super::*;
    use lambda_http::http::StatusCode;
    use lambda_http::{http, Body};

    #[tokio::test]
    async fn main_handles() {
      
        let request = http::Request::builder()
            .uri("https://api.com/?first_name=John")
            .header("Content-Type", "application/json")
            .body(Body::Empty)
            .expect("failed to build request");

        let expected = json!({"first_name": "John"}).into_response();
        let response = func(request, Context::default())
            .await
            .expect("expected Ok(_) value")
            .into_response();
        assert_eq!(response.body(), expected.body());
        assert_eq!(response.status(), StatusCode::OK)
    }
}

Can you go into a little bit of detail about how this goes wrong? People don’t always have a compiler handy when reading these forums.

Sure, the event request I pass the query param but it does not appear in the function. As you can see the query_string_parameters is: StrMap({}) stays empty.

So it looks to me that the Request is not complete or should be different?

Event is: Request { method: GET, uri: https://api.com/?first_name=John, version: HTTP/1.1, headers: {"content-type": "application/json"}, body: Empty }
Event headers: {"content-type": "application/json"}
query_string_parameters is: StrMap({})
thread 'tests::main_handles' panicked at 'assertion failed: `(left == right)`
  left: `Text("Empty first name")`,
 right: `Text("{\"first_name\":\"John\"}")`', hello/src/main.rs:75:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test tests::main_handles ... FAILED

The lambda_http crate has a with_query_string_parameters method that is supposed to be used for populating query_string_parameters in tests. However, it is marked cfg(test) which means that it can't be called from other crates (because it is only built into the test harness for lambda_http itself):

https://docs.rs/lambda_http/0.1.1/src/lambda_http/ext.rs.html#99

How could I use this function in my code then? I'm new to Rust so this is new to me in howto use this.

I think you will need to wait for lambda_http to fix this problem. I can't see any way to do it in the current version of lambda_http. I commented on your issue with a suggested solution.

1 Like

Thnx for the reply. I will wait for the reply of the maintainers then.

This PR solves the issue https://github.com/awslabs/aws-lambda-rust-runtime/pull/253

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.