/** * 测试数据工厂 * 生成各种测试数据,支持边界条件和异常数据 */ import { faker } from '@faker-js/faker'; import { zh_CN } from '@faker-js/faker/locale/zh_CN'; faker.locale = zh_CN; export interface UserData { id?: number; username: string; realName: string; email: string; phone: string; password: string; confirmPassword: string; gender: number; status: number; avatar?: string; createBy?: string; updateBy?: string; createdAt?: string; updatedAt?: string; } export interface RoleData { id?: number; roleName: string; roleCode: string; description: string; status: number; permissions?: string[]; createBy?: string; updateBy?: string; createdAt?: string; updatedAt?: string; } export interface MenuData { id?: number; menuName: string; menuCode: string; path: string; icon: string; sortOrder: number; status: number; parentId: number; menuType: number; component?: string; permission?: string; createBy?: string; updateBy?: string; createdAt?: string; updatedAt?: string; } export interface AlmanacData { date: string; lunarDate: string; ganZhi: string; zodiac: string; yi: string[]; ji: string[]; jieQi?: string; sha?: string; jiShen?: string[]; xiongShen?: string[]; } export interface CalendarData { year: number; month: number; day: number; lunarYear: number; lunarMonth: number; lunarDay: number; lunarMonthName: string; lunarDayName: string; ganZhiYear: string; ganZhiMonth: string; ganZhiDay: string; zodiac: string; isLeapMonth: boolean; isToday: boolean; } class TestDataFactory { /** * 生成正常用户数据 */ generateUserData(overrides: Partial = {}): UserData { const timestamp = Date.now(); const password = 'Test@123456'; return { username: `testuser_${timestamp}`, realName: faker.person.fullName(), email: `test_${timestamp}@example.com`, phone: `1${faker.string.numeric(10)}`, password, confirmPassword: password, gender: faker.number.int({ min: 0, max: 2 }), status: 1, ...overrides, }; } /** * 生成边界条件用户数据 */ generateBoundaryUserData(type: 'min' | 'max' | 'empty' | 'special'): Partial { const timestamp = Date.now(); switch (type) { case 'min': return { username: 'abc', nickname: '测', email: 'test@example.com', phone: '13800138000', password: 'A1@aaaa', confirmPassword: 'A1@aaaa', roleIds: [1], // 添加默认角色 }; case 'max': return { username: 'a'.repeat(20), nickname: '测'.repeat(50), email: `test${timestamp}@example.com`, phone: '13800138000', password: 'A1@' + 'a'.repeat(17), confirmPassword: 'A1@' + 'a'.repeat(17), roleIds: [1], }; case 'empty': return { username: '', nickname: '', email: '', phone: '', password: '', confirmPassword: '', roleIds: [], }; case 'special': return { username: `test_${timestamp}`, nickname: '测试', email: `test+${timestamp}@example.com`, phone: '13800138000', password: 'Test@123!@#$%^&*()', confirmPassword: 'Test@123!@#$%^&*()', roleIds: [1], }; default: return {}; } } /** * 生成异常用户数据 */ generateInvalidUserData(type: 'duplicate' | 'invalid_email' | 'invalid_phone' | 'weak_password'): Partial { const timestamp = Date.now(); switch (type) { case 'duplicate': return { username: 'admin', email: 'admin@example.com', }; case 'invalid_email': return { email: 'invalid-email', }; case 'invalid_phone': return { phone: '12345678901', }; case 'weak_password': return { password: '123456', confirmPassword: '123456', }; default: return {}; } } /** * 生成角色数据 */ generateRoleData(overrides: Partial = {}): RoleData { const timestamp = Date.now(); return { roleName: `测试角色_${timestamp}`, roleCode: `test_role_${timestamp}`, description: faker.lorem.sentence(), status: 1, permissions: [], ...overrides, }; } /** * 生成菜单数据 */ generateMenuData(overrides: Partial = {}): MenuData { const timestamp = Date.now(); return { menuName: `测试菜单_${timestamp}`, menuCode: `test_menu_${timestamp}`, path: `/test-menu-${timestamp}`, icon: 'SettingOutlined', sortOrder: faker.number.int({ min: 1, max: 100 }), status: 0, parentId: 0, menuType: 1, ...overrides, }; } /** * 生成黄历数据 */ generateAlmanacData(date: string = new Date().toISOString().split('T')[0]): AlmanacData { return { date, lunarDate: '农历日期', ganZhi: '甲子年 丙寅月 戊辰日', zodiac: '鼠', yi: ['嫁娶', '祭祀', '祈福', '求嗣', '开光', '出行'], ji: ['开市', '立券', '交易', '纳财'], jieQi: '立春', sha: '南', jiShen: ['天德', '月德', '天恩'], xiongShen: ['月破', '大耗', '四击'], }; } /** * 生成日历数据 */ generateCalendarData(year: number = new Date().getFullYear(), month: number = new Date().getMonth() + 1): CalendarData { return { year, month, day: 15, lunarYear: year, lunarMonth: month, lunarDay: 15, lunarMonthName: '正月', lunarDayName: '十五', ganZhiYear: '甲子', ganZhiMonth: '丙寅', ganZhiDay: '戊辰', zodiac: '鼠', isLeapMonth: false, isToday: false, }; } /** * 生成批量测试数据 */ generateBatchData( generator: () => T, count: number, overrides: Partial = {} ): T[] { return Array.from({ length: count }, () => ({ ...generator(), ...overrides, })); } /** * 生成测试日期范围 */ generateDateRange(days: number = 30): { start: string; end: string } { const end = new Date(); const start = new Date(); start.setDate(start.getDate() - days); return { start: start.toISOString().split('T')[0], end: end.toISOString().split('T')[0], }; } /** * 生成特殊日期 */ generateSpecialDates(): Record { const year = new Date().getFullYear(); return { newYear: `${year}-01-01`, springFestival: `${year}-02-10`, // 示例春节日期 laborDay: `${year}-05-01`, nationalDay: `${year}-10-01`, leapYearFeb29: `${year % 4 === 0 ? year : year + 4}-02-29`, }; } } export const testDataFactory = new TestDataFactory();