使用 HttpMock 測試 API 請求

我們將有一個基本的 rust 程序,它向一個網絡地址發出 HTTP GET 請求,將返回一個包含 10 個用戶的響應。我們需要測試驗證當 API 時,函數是否正確地返回了用戶。

下面列出了將要使用的依賴項:

讓我們創建 struct,用於保存用戶信息:

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Debug, Serialize, Eq, PartialEq)]
struct User {
    idi32,
    nameString,
}

接下來,我們構建向服務發出請求的函數:

async fn make_request(base_urlUri) -> Result<Vec<User>> {
    let client = Client::new();
    let resp = client.get(base_url).await?;
    let body = hyper::body::aggregate(resp).await?;
    let users = serde_json::from_reader(body.reader())?;

    Ok(users)
}

#[tokio::main]
async fn main() -> Result<()> {
    let service = "http://jsonplaceholder.typicode.com/users".parse()?;
    make_request(service).await?;
    Ok(())
}

最後,讓我們爲上面的函數創建單元測試:

#[cfg(test)]
mod tests {
    use httpmock::prelude::*;
    use serde_json::json;
    use crate::{make_request, Uri, User};
    // Enables running test asynchronously
    #[actix_rt::test]
    async fn test_expected_response_is_retrieved() {
        let expected = vec![
            User{ id: 1, name: String::from("abcd")},
            User{ id: 2, name: String::from("efgh")}
        ];

        let server = MockServer::start();

        let _hello_mock = server.mock(|when, then| {
            when.method(GET)
                .path("/");
            then.status(200)
                .header("content-type", "text/json")
                .json_body(json!(expected));
        });

        let actual = make_request(server.base_url().parse::<Uri>().unwrap()).await;
        assert!(actual.unwrap().iter().all(|item| expected.contains(item)));
    }
}

運行cargo test,執行結果如下:

running 1 test
test tests::test_expected_response_is_retrieved ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s

本文翻譯自: https://blog.tarkalabs.com/rust-testing-api-requests-httpmock-4cbd6211ad53

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/V6GuO3Uwy77qJaSL4wnIaw