Skip to content

Commit

Permalink
Utility functions for tests
Browse files Browse the repository at this point in the history
We have a few code paths that some url paths can run when we receive invalid input. We'll write one new test: `handler_handles_empty_pokemon` .

The new test, in addition to the one we've already written needs an `ApiGatewayProxyRequest` which is quite large to write out each time. Inside of the `tests` sub-module we can add a helper function to construct and return a new `ApiGatewayProxyRequest`.

The `fake_request` function will accept a `path` that we use in the `path: Some(path)` field of the `ApiGatewayProxyRequest`.

```rust
fn fake_request(
    path: String,
) -> ApiGatewayProxyRequest {
    ApiGatewayProxyRequest {
        resource: None,
        path: Some(path),
        http_method: Method::GET,
        headers: HeaderMap::new(),
        multi_value_headers: HeaderMap::new(),
        query_string_parameters: HashMap::new(),
        multi_value_query_string_parameters:
            HashMap::new(),
        path_parameters: HashMap::new(),
        stage_variables: HashMap::new(),
        request_context:
            ApiGatewayProxyRequestContext {
                account_id: None,
                resource_id: None,
                operation_name: None,
                stage: None,
                domain_name: None,
                domain_prefix: None,
                request_id: None,
                protocol: None,
                identity: ApiGatewayRequestIdentity {
                    cognito_identity_pool_id: None,
                    account_id: None,
                    cognito_identity_id: None,
                    caller: None,
                    api_key: None,
                    api_key_id: None,
                    access_key: None,
                    source_ip: None,
                    cognito_authentication_type: None,
                    cognito_authentication_provider:
                        None,
                    user_arn: None,
                    user_agent: None,
                    user: None,
                },
                resource_path: None,
                authorizer: HashMap::new(),
                http_method: Method::GET,
                request_time: None,
                request_time_epoch: 0,
                apiid: None,
            },
        body: None,
        is_base64_encoded: Some(false),
    }
}
```

and we can use it in the `handler_handles` test.

```rust
async fn handler_handles() {
    let event = fake_request(
        "/api/pokemon/bulbasaur".to_string(),
    );

    assert_eq!(
        handler(event.clone(), Context::default())
            .await
            .unwrap(),
        ApiGatewayProxyResponse {
            status_code: 200,
            headers: HeaderMap::new(),
            multi_value_headers: HeaderMap::new(),
            body: Some(Body::Text(
                serde_json::to_string(&PokemonHp {
                    name: String::from("Bulbasaur"),
                    hp: 45
                },)
                .unwrap()
            )),
            is_base64_encoded: Some(false),
        }
    )
}
```

Our new test will panic because of the `todo` macro, so we can use the `should_panic` attribute macro to test against the expected panic message.

The test will exercise the `400` codepath, which happens when the path doesn't include a Pokemon name. We could return an empty response as if we hadn't found a Pokemon, but it's most likely that an empty path segment is a client mistake, having passed in an empty string or misconstructed the path.

```rust
async fn handler_handles_empty_pokemon() {
    let event =
        fake_request("/api/pokemon//".to_string());
    handler(event.clone(), Context::default())
        .await
        .unwrap();
}
```

All tests should pass at this point
  • Loading branch information
ChristopherBiscardi committed Oct 17, 2021
1 parent 0d65556 commit bba9647
Showing 1 changed file with 40 additions and 24 deletions.
64 changes: 40 additions & 24 deletions crates/pokemon-api/src/main.rs
Expand Up @@ -78,11 +78,46 @@ mod tests {

#[tokio::test]
async fn handler_handles() {
let event = ApiGatewayProxyRequest {
let event = fake_request(
"/api/pokemon/bulbasaur".to_string(),
);

assert_eq!(
handler(event.clone(), Context::default())
.await
.unwrap(),
ApiGatewayProxyResponse {
status_code: 200,
headers: HeaderMap::new(),
multi_value_headers: HeaderMap::new(),
body: Some(Body::Text(
serde_json::to_string(&PokemonHp {
name: String::from("Bulbasaur"),
hp: 45
},)
.unwrap()
)),
is_base64_encoded: Some(false),
}
)
}

#[tokio::test]
#[should_panic(expected = "not yet implemented")]
async fn handler_handles_empty_pokemon() {
let event =
fake_request("/api/pokemon//".to_string());
handler(event.clone(), Context::default())
.await
.unwrap();
}

fn fake_request(
path: String,
) -> ApiGatewayProxyRequest {
ApiGatewayProxyRequest {
resource: None,
path: Some(
"/api/pokemon/bulbasaur".to_string(),
),
path: Some(path),
http_method: Method::GET,
headers: HeaderMap::new(),
multi_value_headers: HeaderMap::new(),
Expand Down Expand Up @@ -126,25 +161,6 @@ mod tests {
},
body: None,
is_base64_encoded: Some(false),
};

assert_eq!(
handler(event.clone(), Context::default())
.await
.unwrap(),
ApiGatewayProxyResponse {
status_code: 200,
headers: HeaderMap::new(),
multi_value_headers: HeaderMap::new(),
body: Some(Body::Text(
serde_json::to_string(&PokemonHp {
name: String::from("Bulbasaur"),
hp: 45
},)
.unwrap()
)),
is_base64_encoded: Some(false),
}
)
}
}
}

0 comments on commit bba9647

Please sign in to comment.