testing - 使用带有 actix-web 的工作 POST 路由的测试超时
问题描述
我已成功将 Web 应用程序从Rocket迁移到actix-web。通过使用邮递员,我已经验证了相同的请求会产生相同的响应。然而,事实证明迁移测试有点棘手。
我的 POST 请求在运行时超时cargo test
,即使应用程序在运行时只是接受并返回预期的响应就好了cargo run
。
#[cfg(test)]
mod test {
use actix_web::{client, http, test, App};
#[test]
fn main() {
let mut ts = TestSuite::new();
assert!(ts.get_request("/health").status().is_success()); // works
let filter_test_body =
r#"{"key_1":[{"id":"a string"},{"id":"another string"}],"int_1":100}"#;
assert!(
ts.post_request("/post_route", filter_test_body)
.status()
.is_success()
); // times out while actual app returns success with same payload within a few ms
}
fn create_app() -> App<project_name::AppState> {
// {...} some initialization and defining app_state
return App::with_state(&app_state)
.resource("/health", |r| {
r.method(http::Method::GET).f(project_name::health)
})
.resource("/post_route", |r| {
r.method(http::Method::POST)
.with(project_name::post_route_handler)
});
}
struct TestSuite {
server: test::TestServer,
}
impl TestSuite {
pub fn new() -> TestSuite {
TestSuite {
server: test::TestServer::with_factory(create_app),
}
}
pub fn get_request(&mut self, endpoint: &str) -> client::ClientResponse {
let request = self.server
.client(http::Method::GET, endpoint)
.finish()
.unwrap();
self.server.execute(request.send()).unwrap()
}
pub fn post_request(&mut self, endpoint: &str, body: &str) -> client::ClientResponse {
let request_payload: other_lib::request::RequestPayload =
serde_json::from_str(body).unwrap();
let request = self.server
.client(http::Method::POST, endpoint)
.header(http::header::CONTENT_TYPE, "application/json")
.json(request_payload)
//.body(body.to_string())
.unwrap();
self.server.execute(request.send()).unwrap() // thread 'test::main' panicked at 'called `Result::unwrap()` on an `Err` value: Timeout'
}
}
}
相比之下,这是使用 Rocket 的代码库中的 POST 测试。
#[test]
fn test_filters() {
let client = mount_test_rocket(); // getting access to the test server (rocket::local::Client)
let mut response = client.post("/post_route").header(ContentType::JSON)
.body(r#"{"key_1":[{"id":"a string"},{"id":"another string"}],"int_1":100}"#).dispatch();
assert_eq!(response.status(), Status::Ok);
// + more assertions looking into the actual response body
}
解决方案
解决方案很简单。事实证明,请求确实超时了cargo test
。一个潜在的解决方案是将方法放入链中,或者在我的情况下更简单,通过传入标志timeout
来打开我在运行应用程序时使用的相同优化。--release
推荐阅读
- vbscript - 使用 ASP Vbscript 从 base64 数据在服务器端保存 PNG
- c - 是否有一种语法上简短的方法来初始化堆上的结构指针?
- ios - 控制从第一个 VC 到另一个 VC 的操作并取回数据?
- python - 如何将数据框列的文本拆分为多列?
- angular - 如何在角度 7 中动态添加使用 for 循环的表单控件?
- python - 将一串数字和字母转换成一串数字
- mysql - TypeError:从mysql DB获取数据时将循环结构转换为JSON
- python - 属性错误:“加入”对象没有属性“隐式返回”
- windows - 无法从 cmd 使用 ssh 进行连接
- android - “getItem”的返回类型不是被覆盖成员的返回类型的子类型