Unit Tests For Mongo Insert Call?

Hi all!

I have some code here for a serverless Rust lambda function. The idea is that when it is invoked it inserts a document into a MongoDB collection (still rough around the edges and not even looking at the request body, but yeah...)

Is this more or less the correct way to do it?

Should I be doing anything fancy about keeping the mongo connection open?

Also, what is the best way to update my unit test so that it doesn't actually try to use a real database (ideal solution would also be easy to run on a ci server without having to run a local mongo instance).

Thanks! :pray:


   
use chrono::{TimeZone, Utc};
use lambda_http::{handler, lambda, Context, IntoResponse, Request};
use mongodb::bson::doc;
use serde_json::json;
use std::env;

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

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda::run(handler(hello)).await?;
    Ok(())
}

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

    println!("Connecting to MongoDB...");
    
    let connection_string = env::var("MONGO_CONNECTION_STRING").is_err();
    
    println!("Connection string: {}", connection_string);
    
    let client_options = ClientOptions::parse(
        "mongodb+srv://<username>:<password>@cluster0.hx67j.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",
    )
    .await?;
    let client = Client::with_options(client_options)?;
    let database = client.database("testDB");

    let new_doc = doc! {
       "title": req.body["title"],
       "year": 2020,
       "plot": "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. But their easy life gets complicated when their deception is threatened with exposure.",
       "released": Utc.ymd(2020, 2, 7).and_hms(0, 0, 0),
    };

    let insert_result = movies.insert_one(new_doc.clone(), None).await?;

    println!("New document ID: {}", insert_result.inserted_id);

    Ok(json!({
        "success": true
    }))
}

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

    #[tokio::test]
    async fn hello_handles() {
        let request = Request::default();
        let expected = json!({
            "message": "Go Serverless v1.0! Your function executed successfully!"
        })
        .into_response();
        let response = hello(request, Context::default())
            .await
            .expect("expected Ok(_) value")
            .into_response();
        assert_eq!(response.body(), expected.body())
    }
}

This line doesn't look right. Result::is_err is a not an unwrap-type method, it just returns false if the value is an Ok or true if it's an Err. Probably you want instead either

let connection_string = env::var("MONGO_CONNECTION_STRING")?;

or

let connection_string = env::var("MONGO_CONNECTION_STRING").expect("missing or invalid MONGO_CONNECTION_STRING");
1 Like

Thanks @cole-miller :+1:

I still can't actually run my lambda function locally yet so that was just a rough 1st pass at it... :sweat_smile:

How bout those unit tests though?!

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.