使用 HttpMock 測試 API 請求
我們將有一個基本的 rust 程序,它向一個網絡地址發出 HTTP GET 請求,將返回一個包含 10 個用戶的響應。我們需要測試驗證當 API 時,函數是否正確地返回了用戶。
下面列出了將要使用的依賴項:
-
hyper:構建 http client,用於發送 GET 請求。
-
tokio:異步運行時
-
serde,serde-json:序列化將從服務端接收到的 JSON 響應
-
actix-rt:以異步模式運行測試
-
httpmock:在調用某個服務時模擬響應
讓我們創建 struct,用於保存用戶信息:
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Serialize, Eq, PartialEq)]
struct User {
id: i32,
name: String,
}
接下來,我們構建向服務發出請求的函數:
async fn make_request(base_url: Uri) -> 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