test-server.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { OpenAPIHono } from '@hono/zod-openapi';
  2. import { Hono } from 'hono';
  3. import { DataSource } from 'typeorm';
  4. export interface TestServerOptions {
  5. setupAuth?: boolean;
  6. setupDatabase?: boolean;
  7. setupMiddlewares?: boolean;
  8. }
  9. /**
  10. * 创建测试服务器实例
  11. */
  12. export function createTestServer(
  13. app: OpenAPIHono | Hono,
  14. options: TestServerOptions = {}
  15. ) {
  16. const server = app as any;
  17. // 设置默认选项
  18. const {
  19. setupAuth = true
  20. } = options;
  21. return {
  22. get: (path: string, headers?: Record<string, string>) =>
  23. makeRequest('GET', path, undefined, headers),
  24. post: (path: string, body?: any, headers?: Record<string, string>) =>
  25. makeRequest('POST', path, body, headers),
  26. put: (path: string, body?: any, headers?: Record<string, string>) =>
  27. makeRequest('PUT', path, body, headers),
  28. delete: (path: string, headers?: Record<string, string>) =>
  29. makeRequest('DELETE', path, undefined, headers),
  30. patch: (path: string, body?: any, headers?: Record<string, string>) =>
  31. makeRequest('PATCH', path, body, headers)
  32. };
  33. async function makeRequest(
  34. method: string,
  35. path: string,
  36. body?: any,
  37. customHeaders?: Record<string, string>
  38. ) {
  39. const url = new URL(path, 'http://localhost:3000');
  40. const headers: Record<string, string> = {
  41. 'Content-Type': 'application/json',
  42. ...(setupAuth && { 'Authorization': 'Bearer test-token-123' }),
  43. ...customHeaders
  44. };
  45. const request = new Request(url.toString(), {
  46. method,
  47. headers,
  48. body: body ? JSON.stringify(body) : undefined,
  49. });
  50. try {
  51. const response = await server.fetch(request);
  52. const responseHeaders: Record<string, string> = {};
  53. response.headers.forEach((value: string, key: string) => {
  54. responseHeaders[key] = value;
  55. });
  56. let responseData: any;
  57. const contentType = response.headers.get('content-type');
  58. if (contentType?.includes('application/json')) {
  59. responseData = await response.json();
  60. } else {
  61. responseData = await response.text();
  62. }
  63. return {
  64. status: response.status,
  65. headers: responseHeaders,
  66. data: responseData,
  67. json: async () => responseData,
  68. text: async () => responseData
  69. };
  70. } catch (error) {
  71. throw new Error(`Request failed: ${error}`);
  72. }
  73. }
  74. }
  75. /**
  76. * 创建完整的测试应用实例
  77. */
  78. export async function createTestApp(routes: any[]) {
  79. const app = new OpenAPIHono();
  80. // 注册所有路由
  81. routes.forEach(route => {
  82. if (typeof route === 'function') {
  83. route(app);
  84. }
  85. });
  86. return app;
  87. }
  88. /**
  89. * 创建测试数据库连接
  90. */
  91. export async function createTestDataSource(): Promise<DataSource> {
  92. // 使用内存数据库或测试数据库
  93. const dataSource = new DataSource({
  94. type: 'better-sqlite3',
  95. database: ':memory:',
  96. synchronize: true,
  97. logging: false,
  98. entities: [], // 需要根据实际实体配置
  99. });
  100. await dataSource.initialize();
  101. return dataSource;
  102. }