A unit test invokes a small part of a Rust web application and checks its behavior. Tests here exercise HTTP handlers directly or verify individual HTTP parsing and response-building functions. section 7.6 section 2.3.1
A handler test can:
- Construct request parameters and application state, invoke the handler, and check its response. section 4.3.4
- Check status codes, parsed request fields, or the serialized form of an HTTP response. section 2.3.1 section 2.3.2
- Run tests with Cargo; passing tests only verify the behavior actually implemented, so unconditional success responses can pass before database logic exists. section 4.3.4
Test a handler directly
For a POST handler, create form parameters and template state, call the handler, then assert that the response status is OK. This tests the handler function without simulating a client request through the application; that is treated as integration testing. section 7.6
Listing 4.5 Unit tests for the handler functions
#[cfg(test)]
mod tests {
use super::*; #1
use actix_web::http::StatusCode;
use chrono::NaiveDate;
use dotenv::dotenv;
use sqlx::postgres::PgPool;
use std::env;
use std::sync::Mutex;
#[actix_rt::test]
async fn get_all_courses_success() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect(
"DATABASE_URL is not set in .env file"); #2
let pool: PgPool = PgPool::connect(&database_url).await.unwrap(); #3
let app_state: web::Data<AppState> = web::Data::new(AppState { #4
health_check_response: "".to_string(),
visit_count: Mutex::new(0),
db: pool,
});
let tutor_id: web::Path<(i32,)> = web::Path::from((1,)); #5
let resp = get_courses_for_tutor(app_state, tutor_id).await; #6
assert_eq!(resp.status(), StatusCode::OK); #7
}
#[actix_rt::test]
async fn get_course_detail_test() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect(
"DATABASE_URL is not set in .env file");
let pool: PgPool = PgPool::connect(&database_url).await.unwrap();
let app_state: ... #8
let params: web::Path<(i32, i32)> = web::Path::from((1, 2)); #8
let resp = get_course_details(app_state, params).await; #8
assert_eq!(resp.status(), StatusCode::OK); #8
} #8
#[actix_rt::test] #8
async fn post_course_success() { #8
dotenv().ok(); #8
let database_url = env::var("DATABASE_URL").expect( #8
"DATABASE_URL is not set in .env file"); #8
let pool: PgPool = PgPool::connect(&database_url).await.unwrap(); #8
let app_state: ... #8
let new_course_msg = Course {
course_id: 1,
tutor_id: 1,
course_name: "This is the next course".into(),
posted_time: Some(NaiveDate::from_ymd(2020, 9, 17).and_hms(
14, 01, 11)),
};
let course_param = web::Json(new_course_msg);
let resp = post_new_course(course_param, app_state).await;
assert_eq!(resp.status(), StatusCode::OK);
}
}
See the handler test listing for examples that build application state and invoke handlers for three API operations. section 4.3.4








