alexliesenfeld / httpmock

HTTP mocking library for Rust.
MIT License
435 stars 40 forks source link

Mocking for subsequent request flows #106

Closed meghfossa closed 2 months ago

meghfossa commented 2 months ago

I want to make POST on some /api multiple times, and make assertion that both requests were made correctly. Context is, I'm making chunked requests (say 100 items in each /api request). I want to test that, if I submit 102 items, I see two requests - first one with 100 items, and second with 2 items. I'm not sure how to accomplish this correctly in this library.

I'm happy to contribute with F.A.Q or code comment if I can get this resolved.


#[cfg(test)]
mod tests {
    use super::*;
    use httpmock::{
        Method::{self, GET, POST}, Mock, MockExt, MockServer
    };
    use serde_json::json;

    fn enrich_server(server: &mut MockServer) {
        server.mock(|when, then| {
            when.method(POST)
                .path("/api")
                // .json_body(json!{}) // How do I setup expectation for body 1, and body 2 
                .header("content-type", "application/json")
                .header("Authorization", "Bearer secret");

            then.status(201)
                .header("Content-Type", "text")
                .body("Applied!");
        });
    }

    #[tokio::test]
    async fn feed() {
        // Setup
        let mut server = MockServer::start();
        enrich_server(&mut server);

        // Act
        let data: Vec<_> = (0..=102).collect();
        some_method(data, server.url("/api")).await.expect("to resolve"); 
    }
meghfossa commented 2 months ago

I found the solution - for future readers - all you need to do is create additional mock/when/then. Note that it will throw 404, if data does not match

fn make_server(server: &mut MockServer) {
        let chunk_1: Vec<_> = (0..=99).collect();
        let chunk_2: Vec<_> = (100..=105).collect();

        server.mock(|when, then| {
            when.method(POST)
                .path("/api")
                .header("content-type", "application/json")
                .header("authorization", "Bearer secret")
                .json_body(json!({"components": chunk_1}));
            then.status(201)
                .header("content-type", "text")
                .body("Applied!");
        });

        server.mock(|when, then| {
            when.method(POST)
                .path("/api")
                .header("content-type", "application/json")
                .header("authorization", "Bearer secret")
                .json_body(json!({"components": chunk_2}));
            then.status(201)
                .header("content-type", "text")
                .body("Applied!");
        });
    }
alexliesenfeld commented 2 months ago

Exactly. For more complex expectation checking there is also matches.