42 个版本
0.16.1 | 2024 年 5 月 20 日 |
---|---|
0.15.5 | 2023 年 11 月 2 日 |
0.15.4 | 2021 年 11 月 22 日 |
0.15.2 | 2021 年 3 月 21 日 |
0.5.3 | 2019 年 12 月 19 日 |
#22 在 测试 中
203,179 每月下载量
在 29 crates 中使用
88KB
1.5K SLoC
httptest
提供方便的机制,用于测试本地运行的 HTTP 服务器上的 HTTP 客户端。典型用法如下
- 启动服务器
- 通过添加期望来配置服务器
- 通过向服务器发出请求来测试您的 HTTP 客户端
- 在 Drop 时,服务器会验证所有期望都已满足。
示例测试
#[tokio::test]
async fn test_readme() {
use http_body_util::{BodyExt, Full};
use httptest::{matchers::*, responders::*, Expectation, Server};
use hyper_util::client::legacy::Client;
use serde_json::json;
// Starting a logger within the test can make debugging a failed test
// easier. The mock http server will log::debug every request and response
// received along with what, if any, matcher was found for the request. When
// env_logger is initialized running the test with `RUST_LOG=httptest=debug
// cargo test` can provide that information on stderr.
let _ = pretty_env_logger::try_init();
// Start a server running on a local ephemeral port.
let server = Server::run();
// Configure the server to expect a single GET /foo request and respond
// with a 200 status code.
server.expect(
Expectation::matching(request::method_path("GET", "/foo")).respond_with(status_code(200)),
);
// Configure the server to also receive between 1 and 3 POST /bar requests
// with a json body matching {'foo': 'bar'}, and respond with a json body
// {'result': 'success'}
server.expect(
Expectation::matching(all_of![
request::method("POST"),
request::path("/bar"),
request::body(json_decoded(eq(json!({"foo": "bar"})))),
])
.times(1..=3)
.respond_with(json_encoded(json!({"result": "success"}))),
);
// The server provides server.addr() that returns the address of the
// locally running server, or more conveniently provides a server.url()
// method that gives a fully formed http url to the provided path.
let url = server.url("/foo");
// Now test your http client against the server.
let client = Client::builder(hyper_util::rt::TokioExecutor::new())
.build_http::<Full<hyper::body::Bytes>>();
// Issue the GET /foo to the server.
let resp = client.get(url).await.unwrap();
// Optionally use response matchers to assert the server responded as
// expected.
// Assert the response was a 200.
assert_eq!(200, resp.status().as_u16());
// Issue a POST /bar with {'foo': 'bar'} json body.
let post_req = http::Request::post(server.url("/bar"))
.body(json!({"foo": "bar"}).to_string().into())
.unwrap();
let resp = client.request(post_req).await.unwrap();
// Assert the response was a 200 with a json body of {'result': 'success'}
assert_eq!(200, resp.status().as_u16());
// Read the entire response body into a Vec<u8> to allow using the body
// response matcher.
let body = resp.collect().await.unwrap().to_bytes();
assert_eq!(
json!({"result": "success"}),
serde_json::from_slice::<serde_json::Value>(&body).unwrap()
);
// on Drop the server will assert all expectations have been met and will
// panic if not.
}
依赖关系
~10–21MB
~283K SLoC