use axum::Router;
use axum::body::{Body, to_bytes};
use hyper::{Request, Response, StatusCode};
use serde_json::Value;
use tower::ServiceExt;
pub struct TestApp {
pub router: Router,
}
impl TestApp {
pub fn new(router: Router) -> Self {
Self { router }
}
pub async fn request(&self, req: Request<Body>) -> Response<Body> {
self.router
.clone()
.oneshot(req)
.await
.expect("Request failed")
}
pub async fn get(&self, uri: &str) -> Response<Body> {
let req = Request::builder()
.method("GET")
.uri(uri)
.body(Body::empty())
.unwrap();
self.request(req).await
}
pub async fn post_json(&self, uri: &str, json: Value) -> Response<Body> {
let body = serde_json::to_string(&json).unwrap();
let req = Request::builder()
.method("POST")
.uri(uri)
.header("content-type", "application/json")
.body(Body::from(body))
.unwrap();
self.request(req).await
}
pub async fn json_body(response: Response<Body>) -> Value {
let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap();
serde_json::from_slice(&bytes).unwrap()
}
pub async fn body_string(response: Response<Body>) -> String {
let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap();
String::from_utf8(bytes.to_vec()).unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
use axum::{Json, routing::get};
#[tokio::test]
async fn test_app_get_request() {
let router = Router::new().route("/test", get(|| async { "Hello, World!" }));
let app = TestApp::new(router);
let response = app.get("/test").await;
assert_eq!(response.status(), StatusCode::OK);
let body = TestApp::body_string(response).await;
assert_eq!(body, "Hello, World!");
}
#[tokio::test]
async fn test_app_post_json() {
use serde_json::json;
async fn echo_json(Json(payload): Json<Value>) -> Json<Value> {
Json(payload)
}
let router = Router::new().route("/echo", axum::routing::post(echo_json));
let app = TestApp::new(router);
let test_json = json!({"message": "test"});
let response = app.post_json("/echo", test_json.clone()).await;
assert_eq!(response.status(), StatusCode::OK);
let body = TestApp::json_body(response).await;
assert_eq!(body, test_json);
}
}