Berikut adalah contoh penggunaan mockall
untuk mocking dependencies pada Actix-Web, beserta unit test:
- Buat sebuah service yang akan diuji, misalnya
user_service.rs
:
use actix_web::{get, web, Responder};
use mockall::predicate::*;
use mockall::MockResult;
#[derive(Debug)]
pub struct UserService {
pub db: Box<dyn UserRepository>,
}
#[get("/users/{id}")]
async fn get_user(
web::Path(id): web::Path<String>,
service: web::Data<UserService>,
) -> impl Responder {
let user = service.db.get_user(&id).await.unwrap_or_else(|_| None);
format!("User: {:?}", user)
}
pub trait UserRepository {
async fn get_user(&self, id: &str) -> Result<Option<User>, anyhow::Error>;
}
#[derive(Debug)]
pub struct User {
pub id: String,
pub name: String,
}
- Buat mock untuk
UserRepository
menggunakanmockall
:
use mockall::mock;
mock! {
pub UserRepository {
async fn get_user(&self, id: &str) -> Result<Option<User>, anyhow::Error>;
}
}
- Tulis unit test yang menggunakan mock
UserRepository
:
use actix_web::{test, web, App};
use mockall::predicate::*;
use user_service::{get_user, User, UserRepository, UserService};
#[actix_web::test]
async fn test_get_user() {
let mut mock_repo = MockUserRepository::new();
mock_repo
.expect_get_user()
.with(eq("123"))
.returning(|| Ok(Some(User {
id: "123".to_string(),
name: "John Doe".to_string(),
})));
let app = test::init_service(
App::new()
.app_data(web::Data::new(UserService {
db: Box::new(mock_repo),
}))
.service(get_user),
)
.await;
let req = test::TestRequest::with_path("/users/123").to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_success());
let body = test::read_body(resp).await;
assert_eq!(body, b"User: User { id: \"123\", name: \"John Doe\" }");
}
Dalam contoh ini, kita membuat sebuah mock UserRepository
menggunakan mockall
. Kemudian, kita mengkonfigurasi mock untuk mengembalikan data yang diharapkan ketika metode get_user
dipanggil dengan parameter "123"
.
Selanjutnya, kita membuat sebuah aplikasi Actix-Web yang menggunakan UserService
dengan mock UserRepository
, dan menjalankan unit test untuk memastikan bahwa endpoint /users/{id}
mengembalikan respons yang diharapkan.
Dengan menggunakan mockall
, Anda dapat dengan mudah menyediakan mock dependencies untuk unit test, sehingga Anda dapat menguji logika aplikasi tanpa harus bergantung pada implementasi yang sebenarnya.
Sedangkan untuk file Cargo.toml
[package]
name = "actix-web-mockall-example"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4.2.1"
mockall = "0.11.0"
anyhow = "1.0.68"