get.test.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { OpenAPIHono } from '@hono/zod-openapi';
  2. import { UserService } from '../../../modules/users/user.service';
  3. import { DataSource } from 'typeorm';
  4. import { createTestServer } from '../../../../test/test-utils';
  5. import { describe, it, expect, beforeEach, vi } from 'vitest';
  6. // Mock 用户服务
  7. vi.mock('../../../modules/users/user.service');
  8. // Mock 数据源
  9. vi.mock('../../../data-source', () => ({
  10. AppDataSource: {
  11. getRepository: vi.fn()
  12. }
  13. }));
  14. // Mock 认证中间件
  15. vi.mock('../../../middleware/auth.middleware', () => ({
  16. authMiddleware: vi.fn().mockImplementation((c, next) => next())
  17. }));
  18. describe('GET /users API', () => {
  19. let app: OpenAPIHono;
  20. let mockUserService: any;
  21. beforeEach(async () => {
  22. vi.clearAllMocks();
  23. // 创建模拟的用户服务
  24. mockUserService = {
  25. getUsersWithPagination: vi.fn()
  26. } as any;
  27. // Mock UserService 构造函数
  28. vi.mocked(UserService).mockImplementation(() => mockUserService);
  29. // 动态导入以避免缓存问题
  30. const module = await import('../get');
  31. app = module.default;
  32. });
  33. describe('参数验证', () => {
  34. it('应该验证页码必须为正整数', async () => {
  35. const server = createTestServer(app);
  36. const response = await server.get('/?page=0');
  37. expect(response.status).toBe(400);
  38. const responseBody = await response.json();
  39. expect(responseBody.success).toBe(false);
  40. expect(responseBody.error).toBeDefined();
  41. expect(responseBody.error.name).toBe('ZodError');
  42. });
  43. it('应该验证每页数量必须为正整数', async () => {
  44. const server = createTestServer(app);
  45. const response = await server.get('/?pageSize=0');
  46. expect(response.status).toBe(400);
  47. const responseBody = await response.json();
  48. expect(responseBody.success).toBe(false);
  49. expect(responseBody.error).toBeDefined();
  50. expect(responseBody.error.name).toBe('ZodError');
  51. });
  52. it('应该接受有效的分页参数', async () => {
  53. const mockUsers = [{ id: 1, username: 'testuser' }];
  54. const total = 1;
  55. mockUserService.getUsersWithPagination.mockResolvedValue([mockUsers as any, total]);
  56. const server = createTestServer(app);
  57. const response = await server.get('/?page=1&pageSize=10');
  58. expect(response.status).toBe(200);
  59. expect(mockUserService.getUsersWithPagination).toHaveBeenCalledWith({
  60. page: 1,
  61. pageSize: 10,
  62. keyword: undefined
  63. });
  64. });
  65. });
  66. describe('成功响应', () => {
  67. it('应该返回用户列表和分页信息', async () => {
  68. const mockUsers = [
  69. { id: 1, username: 'user1', email: 'user1@example.com' },
  70. { id: 2, username: 'user2', email: 'user2@example.com' }
  71. ];
  72. const total = 2;
  73. mockUserService.getUsersWithPagination.mockResolvedValue([mockUsers as any, total]);
  74. const server = createTestServer(app);
  75. const response = await server.get('/?page=1&pageSize=10');
  76. expect(response.status).toBe(200);
  77. expect(await response.json()).toEqual({
  78. data: mockUsers,
  79. pagination: {
  80. total: 2,
  81. current: 1,
  82. pageSize: 10
  83. }
  84. });
  85. });
  86. it('应该支持关键词搜索', async () => {
  87. const mockUsers = [{ id: 1, username: 'admin' }];
  88. const total = 1;
  89. mockUserService.getUsersWithPagination.mockResolvedValue([mockUsers as any, total]);
  90. const server = createTestServer(app);
  91. const response = await server.get('/?page=1&pageSize=10&keyword=admin');
  92. expect(response.status).toBe(200);
  93. expect(mockUserService.getUsersWithPagination).toHaveBeenCalledWith({
  94. page: 1,
  95. pageSize: 10,
  96. keyword: 'admin'
  97. });
  98. });
  99. });
  100. describe('错误处理', () => {
  101. it('应该在服务抛出错误时返回500错误', async () => {
  102. mockUserService.getUsersWithPagination.mockRejectedValue(new Error('Database error'));
  103. const server = createTestServer(app);
  104. const response = await server.get('/?page=1&pageSize=10');
  105. expect(response.status).toBe(500);
  106. expect(await response.json()).toMatchObject({
  107. code: 500,
  108. message: 'Database error'
  109. });
  110. });
  111. it('应该在未知错误时返回通用错误消息', async () => {
  112. mockUserService.getUsersWithPagination.mockRejectedValue('Unknown error');
  113. const server = createTestServer(app);
  114. const response = await server.get('/?page=1&pageSize=10');
  115. expect(response.status).toBe(500);
  116. expect(await response.json()).toMatchObject({
  117. code: 500,
  118. message: '获取用户列表失败'
  119. });
  120. });
  121. });
  122. });