import { describe, it, expect, vi, beforeEach } from 'vitest' import { asyncHandler } from '../asyncHandler' import type { Request, Response, NextFunction } from 'express' describe('asyncHandler', () => { const mockReq = {} as Request const mockRes = {} as Response const mockNext = vi.fn() beforeEach(() => { vi.clearAllMocks() }) describe('成功调用', () => { it('应正常执行函数并返回结果', async () => { const mockHandler = vi.fn().mockResolvedValue('操作成功') const wrappedHandler = asyncHandler(mockHandler) await wrappedHandler(mockReq, mockRes, mockNext) expect(mockHandler).toHaveBeenCalledWith(mockReq, mockRes, mockNext) expect(mockNext).not.toHaveBeenCalled() }) it('应处理返回同步值的函数', async () => { const mockHandler = vi.fn().mockResolvedValue({ id: 1, name: 'test' }) const wrappedHandler = asyncHandler(mockHandler) await wrappedHandler(mockReq, mockRes, mockNext) expect(mockHandler).toHaveBeenCalled() expect(mockNext).not.toHaveBeenCalled() }) }) describe('异常传播', () => { it('应正确传播异步错误', async () => { const asyncError = new Error('异步错误') const mockHandler = vi.fn().mockRejectedValue(asyncError) const wrappedHandler = asyncHandler(mockHandler) await wrappedHandler(mockReq, mockRes, mockNext) expect(mockHandler).toHaveBeenCalled() expect(mockNext).toHaveBeenCalledWith(asyncError) }) it('应处理 Promise.reject 的错误', async () => { const error = new Error('Promise rejected') const mockHandler = vi.fn().mockReturnValue(Promise.reject(error)) const wrappedHandler = asyncHandler(mockHandler) await wrappedHandler(mockReq, mockRes, mockNext) expect(mockNext).toHaveBeenCalledWith(error) }) it('应处理非 Error 对象的异步错误', async () => { const error = '字符串错误' const mockHandler = vi.fn().mockRejectedValue(error) const wrappedHandler = asyncHandler(mockHandler) await wrappedHandler(mockReq, mockRes, mockNext) expect(mockNext).toHaveBeenCalledWith(error) }) }) describe('函数调用时机', () => { it('应立即调用底层函数', () => { const mockHandler = vi.fn().mockResolvedValue('result') const wrappedHandler = asyncHandler(mockHandler) wrappedHandler(mockReq, mockRes, mockNext) expect(mockHandler).toHaveBeenCalled() }) }) })