actix-web+actix-sessionの基本的な使い方はドキュメントのサンプルコードを見れば分かる。
本記事ではテスト方法について書く。
Crate Versions
cargo.toml
[dependencies]
actix-web = "2"
actix-rt = "1"
actix-session = "0.3"
Handler
下のようなHandlerだったとする。
use actix_session::Session;
use actix_web::{error, Error, HttpResponse};
pub async fn example(session: Session) -> Result<HttpResponse, Error> {
let name = session
.get::<String>("name")
.map_err(|e| {
println!("{}", e.to_string());
error::ErrorInternalServerError("Server Error")
})?
.unwrap_or("".to_string());
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(format!("Hello, {}.", name)))
}
テスト
上のexample関数に注入するSessionインスタンスをどう用意するかが問題になる。
ソースのドキュメントを見ると
「Sessionオブジェクト取得するにはUserSession::get_sessionメソッドを使うと良い。UserSessionトレイトはHttpRequestとServiceRequestとRequestHeadに被せることができる」
といったことが書いてあるので、これを使わせてもらう。
そしてactix-webのドキュメントによるとHttpRequestインスタンスを生成するためのテスト用のメソッドが用意されているのでこれを使う。
# [cfg(test)]
mod tests {
use super::*;
use actix_session::UserSession;
use actix_web::dev::ServiceResponse;
use actix_web::{http, test};
#[actix_rt::test]
async fn test_example() {
let req = test::TestRequest::default().to_http_request();
let _ = req.get_session().set("name", "Foo");
let resp = example(req.get_session()).await.unwrap();
assert_eq!(resp.status(), http::StatusCode::OK);
let srv_resp = ServiceResponse::new(req, resp);
let bytes = test::read_body(srv_resp).await;
let body = String::from_utf8(bytes.to_vec()).unwrap();
assert!(body.contains("Hello, Foo."));
}
}
このようにしてSessionインスタンスを注入しテストができた。