如何在Sea-ORM MockDatabase中正确Mock COUNT查询结果用于测试?
问题
我正在测试一个基于Sea-ORM的函数,该函数通过COUNT查询检查数据库中是否存在指定space,但测试始终失败。
仓库代码
pub async fn space_check_exist(db: &DatabaseConnection, space_id: &str) -> Result<bool, DbErr> { let count = Space::find() .filter(space::Column::SpaceId.eq(space_id)) .count(db) .await?; Ok(count > 0) }
测试代码
#[tokio::test] async fn test_space_check_exist_when_space_exists() { let db = MockDatabase::new(DatabaseBackend::Postgres) .append_query_results([vec![space::Model { id: 1, space_id: "test-space-id".to_owned(), space_status_id: 1, space_config: Json::Null, created_at: chrono::Utc::now().naive_utc(), updated_at: chrono::Utc::now().naive_utc(), deleted_at: None, } as space::Model] as Vec<space::Model>]) .into_connection(); // Run test let result = SpaceRepository::space_check_exist(&db, "test-space-id").await; // Verify result // assert!(result.is_ok()); assert!(result.unwrap()); }
测试失败情况
- 执行
assert!(result.is_ok())时,测试panic并提示断言失败; - 执行
assert!(result.unwrap())时,panic提示解码"num_items"遇到空值。
尝试过使用完整的space::Model、不同配置的MockRow来Mock COUNT查询结果,但都无法成功。如何在Sea-ORM中正确Mock COUNT查询结果?
环境
- Rust 1.83.0
- sea-orm 1.1.4
解决方法
问题核心是Mock的数据类型不匹配:COUNT查询返回的是单一数值(对应SQL的COUNT(*)结果),而你Mock的是完整的space::Model实例,Sea-ORM无法将Model映射到COUNT需要的num_items字段,因此出现解码空值错误。
正确做法是直接Mock COUNT查询的返回值,即包含num_items字段的MockRow,而非完整Model。
修改后的测试代码
#[tokio::test] async fn test_space_check_exist_when_space_exists() { // Mock COUNT查询返回1(表示存在匹配记录) let db = MockDatabase::new(DatabaseBackend::Postgres) .append_query_results([vec![MockRow::new([("num_items", 1_i64.into())])]]) .into_connection(); let result = SpaceRepository::space_check_exist(&db, "test-space-id").await; // 验证结果:成功且返回true assert!(result.is_ok()); assert!(result.unwrap()); } // 补充:测试space不存在的场景 #[tokio::test] async fn test_space_check_exist_when_space_not_exists() { // Mock COUNT查询返回0(表示无匹配记录) let db = MockDatabase::new(DatabaseBackend::Postgres) .append_query_results([vec![MockRow::new([("num_items", 0_i64.into())])]]) .into_connection(); let result = SpaceRepository::space_check_exist(&db, "non-existent-id").await; assert!(result.is_ok()); assert!(!result.unwrap()); }
关键说明
- Sea-ORM的
count方法执行SQL后,会返回名为num_items的列(Postgres环境下),因此MockRow必须包含该字段; - COUNT返回值为64位整数,需用
1_i64.into()转换为Sea-ORM的Value类型; - 若需Mock多个查询,需按代码中查询执行顺序依次调用
append_query_results。
内容的提问来源于stack exchange,提问作者localhost80808
相关产品推荐
相关产品推荐

