I'm building a web API service with Rust and actix_web.
I want to test a route and check if the received response body is what I expect. But I'm struggling with converting the received body ResponseBody<Body>
into JSON or BSON. The called route actually returns application/json
.
let mut app = test::init_service(App::new()
.data(AppState { database: db.clone() })
.route("/recipes/{id}", web::post().to(add_one_recipe))
).await;
let payload = create_one_recipe().as_document().unwrap().clone();
let req = test::TestRequest::post()
.set_json(&payload).uri("/recipes/new").to_request();
let mut resp = test::call_service(&mut app, req).await;
let body: ResponseBody<Body> = resp.take_body(); // Here I want the body as Binary, String, JSON, or BSON. The response is actually application/json.
The actix/examples repository achieves this by defining a new trait called BodyTest...
trait BodyTest {
fn as_str(&self) -> &str;
}
impl BodyTest for ResponseBody<Body> {
fn as_str(&self) -> &str {
match self {
ResponseBody::Body(ref b) => match b {
Body::Bytes(ref by) => std::str::from_utf8(&by).unwrap(),
_ => panic!(),
},
ResponseBody::Other(ref b) => match b {
Body::Bytes(ref by) => std::str::from_utf8(&by).unwrap(),
_ => panic!(),
},
}
}
}
After which you may simply do:
assert_eq!(resp.response().body().as_str(), "Your name is John");
This trait is now much simpler (you could skip entirely):
trait BodyTest {
fn as_str(&self) -> &str;
}
impl BodyTest for Bytes {
fn as_str(&self) -> &str {
std::str::from_utf8(self).unwrap()
}
}
And to use it:
let body = to_bytes(resp.into_body()).await.unwrap();
assert_eq!(body.as_str(), "Your name is John");
Reference to full code these excerpts were taken from: https://github.com/actix/examples/blob/master/forms/form/src/main.rs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With