Can not check the transaction log of mock database in actix
framework
#419
-
I'm trying to implement a test with actix framework using sea-orm mocking feature by repeating stuff from documentation and examples, but I'm stuck on implementing assertion of transaction logs. I understand that into_transaction_log can be called only by owned value, but I don't see the way how I can achieve it. My code// imports are omitted for shortening the listing
#[derive(Debug)]
pub struct AppState {
conn: DatabaseConnection,
}
impl AppState {
pub fn new(conn: DatabaseConnection) -> Self {
Self { conn }
}
pub fn get_db_conn(&self) -> &DatabaseConnection {
&self.conn
}
}
#[get("/user/{user_id}")]
pub async fn get_user_by_id(
_req: HttpRequest,
data: web::Data<AppState>,
user_id: web::Path<i32>,
) -> impl Responder {
let conn = (&data).get_db_conn();
match User::find()
.filter(user::Column::Id.eq(user_id.into_inner()))
.one(conn)
.await
{
Err(e) => internal_server_error_with_log(e),
Ok(user) => match user {
None => HttpResponse::NotFound().finish(),
Some(u) => {
println!("{:?}", &u);
let db_result = u.find_related(Country).one(conn).await;
match db_result {
Err(e) => internal_server_error_with_log(e),
Ok(c) => {
let dto = UserWithCountry::from(&(u, c));
println!("{:?}", &dto);
HttpResponse::Ok().json(&dto)
}
}
}
},
}
}
fn internal_server_error_with_log(e: impl std::fmt::Debug) -> HttpResponse {
error!("{:?}", e);
HttpResponse::InternalServerError().finish()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::entity::country;
use actix_web::{test, web::Bytes, App};
use chrono::NaiveDateTime;
use sea_orm::{DatabaseBackend, MockDatabase};
use std::str::FromStr;
#[actix_web::test]
async fn test_find_user_with_country_by_id() {
// initilization of `u` and `c` are omitted for shortening the listing
let db_conn = MockDatabase::new(DatabaseBackend::MySql)
.append_query_results(vec![vec![u]])
.append_query_results(vec![vec![c]])
.into_connection();
let app = test::init_service(
App::new()
.app_data(web::Data::new(AppState::new(db_conn)))
.service(get_user_by_id),
)
.await;
let resp = test::TestRequest::get()
.uri("/user/1")
.send_request(&app)
.await;
assert_eq!(
(*d).get_db_conn().into_transaction_log(), // I don't know what should be written here to make it work
vec![
Transaction::from_sql_and_values(
DatabaseBackend::MySql,
r#"SELECT `users2`.`id`, `users2`.`email`, `users2`.`first_name`, `users2`.`last_name`, `users2`.`age`, `users2`.`country_id`, `users2`.`created_at` FROM `users2` WHERE `users2`.`id` = ? LIMIT ?"#,
vec![1i32.into(), 1i32.into()]
),
Transaction::from_sql_and_values(
DatabaseBackend::MySql,
r#"SELECT `countries2`.`id`, `countries2`.`name` FROM `countries2` INNER JOIN `users2` ON `users2`.`country_id` = `countries2`.`id` WHERE `users2`.`id` = ? LIMIT ?"#,
vec![1i32.into(), 1i32.into()]
),
]
);
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I think so, perhaps you need to add a method to take ownership of the state: impl AppState {
pub fn into_database_connection(self) -> DatabaseConnection {
self.conn
}
} That said, I think the general rule of thumb is, you'd refactor the app logic into a business domain module where there is no If you want to test it on app level, you'd probably want to use a real database, or at least, SQLite. |
Beta Was this translation helpful? Give feedback.
I think so, perhaps you need to add a method to take ownership of the state:
That said, I think the general rule of thumb is, you'd refactor the app logic into a business domain module where there is no
Actix
or any web API dependency.If you want to test it on app level, you'd probably want to use a real database, or at least, SQLite.