//! 虚拟银行测试设置 //! //! 提供虚拟银行的初始化和配置辅助函数 use rust_decimal::Decimal; use rust_decimal_macros::dec; use rustjr::infrastructure::bank_integration::{ BankClient, mock_bank::{FailureConfig, MockBankClient, MockBankTestEnv}, }; use super::fixtures::{ gen_inmate_account_no, FAMILY_ACCOUNT, FAMILY_ACCOUNT_NAME, PRISON_MAIN_ACCOUNT, PRISON_MAIN_ACCOUNT_NAME, }; // ==================== 虚拟银行环境 ==================== /// 标准测试银行环境 pub struct TestBankEnv { /// 虚拟银行客户端 pub client: MockBankClient, /// 监狱主账户号 pub prison_account: String, /// 家属账户号 pub family_account: String, } impl TestBankEnv { /// 创建标准测试环境 /// /// 包含: /// - 监狱主账户:初始余额 1,000,000 /// - 家属账户:初始余额 100,000 pub fn new() -> Self { let client = MockBankClient::new(); // 创建监狱主账户 client .create_account( PRISON_MAIN_ACCOUNT, PRISON_MAIN_ACCOUNT_NAME, dec!(1000000.00), ) .expect("创建监狱账户失败"); // 创建家属账户 client .create_account(FAMILY_ACCOUNT, FAMILY_ACCOUNT_NAME, dec!(100000.00)) .expect("创建家属账户失败"); Self { client, prison_account: PRISON_MAIN_ACCOUNT.to_string(), family_account: FAMILY_ACCOUNT.to_string(), } } /// 创建罪犯子账户 pub fn create_inmate_account( &self, inmate_id: i64, initial_balance: Decimal, ) -> String { let account_no = gen_inmate_account_no(inmate_id); let account_name = format!("罪犯{}账户", inmate_id); self.client .create_account(&account_no, &account_name, initial_balance) .expect("创建罪犯账户失败"); account_no } /// 启用故障注入 pub fn enable_failures(&self) { self.client .set_failure_config(FailureConfig::for_testing()); } /// 禁用故障注入 pub fn disable_failures(&self) { self.client.set_failure_enabled(false); } /// 配置强制超时 pub fn force_timeout(&self) { self.client.set_failure_config(FailureConfig::force_timeout()); } /// 配置强制失败 pub fn force_failure(&self) { self.client.set_failure_config(FailureConfig::force_failure()); } /// 重置环境 pub fn reset(&self) { self.client.reset(); // 重新创建账户 self.client .create_account( PRISON_MAIN_ACCOUNT, PRISON_MAIN_ACCOUNT_NAME, dec!(1000000.00), ) .expect("重建监狱账户失败"); self.client .create_account(FAMILY_ACCOUNT, FAMILY_ACCOUNT_NAME, dec!(100000.00)) .expect("重建家属账户失败"); } } impl Default for TestBankEnv { fn default() -> Self { Self::new() } } // ==================== 快捷创建函数 ==================== /// 创建标准测试银行环境 pub fn setup_test_bank() -> TestBankEnv { TestBankEnv::new() } /// 创建带故障注入的测试银行环境 pub fn setup_test_bank_with_failures() -> TestBankEnv { let env = TestBankEnv::new(); env.enable_failures(); env } /// 创建强制超时的测试银行环境 pub fn setup_test_bank_force_timeout() -> TestBankEnv { let env = TestBankEnv::new(); env.force_timeout(); env } /// 创建强制失败的测试银行环境 pub fn setup_test_bank_force_failure() -> TestBankEnv { let env = TestBankEnv::new(); env.force_failure(); env } // ==================== 验证辅助函数 ==================== /// 验证银行余额 pub async fn assert_bank_balance( client: &MockBankClient, account_no: &str, expected: Decimal, ) { let balance = client.query_balance(account_no).await.expect("查询余额失败"); assert_eq!( balance.balance, expected, "账户 {} 余额不符: 期望 {}, 实际 {}", account_no, expected, balance.balance ); } /// 验证银行可用余额 pub async fn assert_available_balance( client: &MockBankClient, account_no: &str, expected: Decimal, ) { let balance = client.query_balance(account_no).await.expect("查询余额失败"); assert_eq!( balance.available_balance, expected, "账户 {} 可用余额不符: 期望 {}, 实际 {}", account_no, expected, balance.available_balance ); } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_setup_env() { let env = setup_test_bank(); let prison_balance = env.client.query_balance(&env.prison_account).await.unwrap(); assert_eq!(prison_balance.balance, dec!(1000000.00)); let family_balance = env.client.query_balance(&env.family_account).await.unwrap(); assert_eq!(family_balance.balance, dec!(100000.00)); } #[tokio::test] async fn test_create_inmate_account() { let env = setup_test_bank(); let inmate_account = env.create_inmate_account(1001, dec!(5000.00)); let balance = env.client.query_balance(&inmate_account).await.unwrap(); assert_eq!(balance.balance, dec!(5000.00)); } }