integration-test-db.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { DataSource } from 'typeorm';
  2. import { beforeEach, afterEach, afterAll } from 'vitest';
  3. import { UserEntity } from '../modules/users/user.entity';
  4. import { Role } from '../modules/users/role.entity';
  5. import { AppDataSource } from '../data-source';
  6. /**
  7. * 集成测试数据库工具类 - 使用真实PostgreSQL数据库
  8. */
  9. export class IntegrationTestDatabase {
  10. // private static initializationPromise: Promise<DataSource> | null = null;
  11. // /**
  12. // * 初始化集成测试数据库
  13. // */
  14. // static async initialize(): Promise<DataSource> {
  15. // // if (!AppDataSource.isInitialized) {
  16. // // if (!this.initializationPromise) {
  17. // // this.initializationPromise = (async () => {
  18. // // try {
  19. // // await AppDataSource.initialize();
  20. // // return AppDataSource;
  21. // // } catch (error) {
  22. // // this.initializationPromise = null;
  23. // // throw error;
  24. // // }
  25. // // })();
  26. // // }
  27. // // return await this.initializationPromise;
  28. // // }
  29. // // if(!AppDataSource.isInitialized) {
  30. // // await AppDataSource.initialize();
  31. // // }
  32. // return AppDataSource;
  33. // }
  34. /**
  35. * 清理集成测试数据库
  36. */
  37. static async cleanup(): Promise<void> {
  38. if (AppDataSource.isInitialized) {
  39. console.debug('测试数据库断开')
  40. await AppDataSource.destroy();
  41. }
  42. }
  43. /**
  44. * 获取当前数据源
  45. */
  46. static async getDataSource(): Promise<DataSource> {
  47. if(!AppDataSource.isInitialized) {
  48. console.debug('测试数据库初始化')
  49. await AppDataSource.initialize();
  50. }
  51. return AppDataSource
  52. }
  53. // /**
  54. // * 清空所有表数据
  55. // */
  56. // static async clearAllData(): Promise<void> {
  57. // if (!AppDataSource.isInitialized) {
  58. // return;
  59. // }
  60. // const queryRunner = AppDataSource.createQueryRunner();
  61. // await queryRunner.connect();
  62. // try {
  63. // // 获取所有实体
  64. // const entities = AppDataSource.entityMetadatas;
  65. // // 按依赖关系排序(先删除子表,再删除父表)
  66. // const sortedEntities = entities.sort((a, b) => {
  67. // if (a.foreignKeys.some(fk => fk.referencedEntityMetadata.name === b.name)) {
  68. // return 1; // a 依赖于 b,a 应该排在后面
  69. // }
  70. // if (b.foreignKeys.some(fk => fk.referencedEntityMetadata.name === a.name)) {
  71. // return -1; // b 依赖于 a,a 应该排在前面
  72. // }
  73. // return 0;
  74. // });
  75. // // 使用TRUNCATE CASCADE来清空所有表数据(包括有外键约束的表)
  76. // for (const entity of sortedEntities) {
  77. // await queryRunner.query(`TRUNCATE TABLE "${entity.tableName}" CASCADE`);
  78. // }
  79. // } finally {
  80. // await queryRunner.release();
  81. // }
  82. // }
  83. }
  84. /**
  85. * 测试数据工厂类
  86. */
  87. export class TestDataFactory {
  88. /**
  89. * 创建测试用户数据
  90. */
  91. static createUserData(overrides: Partial<UserEntity> = {}): Partial<UserEntity> {
  92. const timestamp = Date.now();
  93. return {
  94. username: `testuser_${timestamp}`,
  95. password: 'TestPassword123!',
  96. email: `test_${timestamp}@example.com`,
  97. phone: `138${timestamp.toString().slice(-8)}`,
  98. nickname: `Test User ${timestamp}`,
  99. name: `Test Name ${timestamp}`,
  100. isDisabled: 0,
  101. isDeleted: 0,
  102. ...overrides
  103. };
  104. }
  105. /**
  106. * 创建测试角色数据
  107. */
  108. static createRoleData(overrides: Partial<Role> = {}): Partial<Role> {
  109. const timestamp = Date.now();
  110. return {
  111. name: `test_role_${timestamp}`,
  112. description: `Test role description ${timestamp}`,
  113. ...overrides
  114. };
  115. }
  116. /**
  117. * 在数据库中创建测试用户
  118. */
  119. static async createTestUser(dataSource: DataSource, overrides: Partial<UserEntity> = {}): Promise<UserEntity> {
  120. const userData = this.createUserData(overrides);
  121. const userRepository = dataSource.getRepository(UserEntity);
  122. const user = userRepository.create(userData);
  123. return await userRepository.save(user);
  124. }
  125. /**
  126. * 在数据库中创建测试角色
  127. */
  128. static async createTestRole(dataSource: DataSource, overrides: Partial<Role> = {}): Promise<Role> {
  129. const roleData = this.createRoleData(overrides);
  130. const roleRepository = dataSource.getRepository(Role);
  131. const role = roleRepository.create(roleData);
  132. return await roleRepository.save(role);
  133. }
  134. }
  135. /**
  136. * 集成测试数据库生命周期钩子
  137. */
  138. export function setupIntegrationDatabaseHooks() {
  139. beforeEach(async () => {
  140. await IntegrationTestDatabase.getDataSource();
  141. });
  142. // afterEach(async () => {
  143. // await IntegrationTestDatabase.clearAllData();
  144. // });
  145. afterEach(async () => {
  146. console.debug('测试数据库断开')
  147. await IntegrationTestDatabase.cleanup();
  148. });
  149. }