Files
gym-manage/gym-manage-web/src/__tests__/utils/errorHandler.test.ts
T
张翔 ae9be86527 refactor(test): reorganize test directory structure
- Move test files from src/test/ to src/__tests__/
- Follow Vitest convention for test directory naming
- Improve test organization and discoverability
2026-04-23 16:34:03 +08:00

234 lines
7.1 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { ElMessage } from 'element-plus'
import { handleApiError, ApiErrorHandler } from '@/utils/errorHandler'
vi.mock('element-plus', () => ({
ElMessage: {
error: vi.fn(),
success: vi.fn(),
},
}))
describe('errorHandler', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.stubGlobal('localStorage', {
removeItem: vi.fn(),
})
vi.stubGlobal('window', {
location: { href: '' },
})
})
describe('handleApiError', () => {
it('should call ApiErrorHandler.handle', () => {
const mockError = { response: { status: 500, data: {} } }
const handleSpy = vi.spyOn(ApiErrorHandler, 'handle')
handleApiError(mockError)
expect(handleSpy).toHaveBeenCalledWith(mockError)
})
})
describe('ApiErrorHandler.handle', () => {
it('should handle network error', () => {
const mockError = new Error('Network Error')
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('网络连接失败,请检查网络设置')
expect(consoleSpy).toHaveBeenCalledWith('Network Error:', mockError)
})
it('should handle 400 Bad Request', () => {
const mockError = {
response: {
status: 400,
data: { message: 'Invalid parameters' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('Invalid parameters')
expect(consoleSpy).toHaveBeenCalledWith('Bad Request:', mockError.response.data)
})
it('should handle 401 Unauthorized', () => {
const mockError = {
response: {
status: 401,
data: { message: 'Unauthorized' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('登录已过期,请重新登录')
expect(localStorage.removeItem).toHaveBeenCalledWith('token')
expect(window.location.href).toBe('/login')
expect(consoleSpy).toHaveBeenCalledWith('Unauthorized:', mockError.response.data)
})
it('should handle 403 Forbidden', () => {
const mockError = {
response: {
status: 403,
data: { message: 'Access denied' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('没有权限访问该资源')
expect(consoleSpy).toHaveBeenCalledWith('Forbidden:', mockError.response.data)
})
it('should handle 404 Not Found', () => {
const mockError = {
response: {
status: 404,
data: { message: 'Resource not found' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('Resource not found')
expect(consoleSpy).toHaveBeenCalledWith('Not Found:', mockError.response.data)
})
it('should handle 409 Conflict', () => {
const mockError = {
response: {
status: 409,
data: { message: 'Resource conflict' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('Resource conflict')
expect(consoleSpy).toHaveBeenCalledWith('Conflict:', mockError.response.data)
})
it('should handle 422 Validation Error with details', () => {
const mockError = {
response: {
status: 422,
data: {
message: 'Validation failed',
details: {
username: 'Username is required',
password: 'Password is too short',
},
},
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('Username is required、Password is too short')
expect(consoleSpy).toHaveBeenCalledWith('Validation Error:', mockError.response.data)
})
it('should handle 422 Validation Error without details', () => {
const mockError = {
response: {
status: 422,
data: { message: 'Validation failed' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('Validation failed')
expect(consoleSpy).toHaveBeenCalledWith('Validation Error:', mockError.response.data)
})
it('should handle 500 Internal Server Error', () => {
const mockError = {
response: {
status: 500,
data: { message: 'Server error' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('服务器内部错误,请稍后重试')
expect(consoleSpy).toHaveBeenCalledWith('Internal Server Error:', mockError.response.data)
})
it('should handle 502 Service Unavailable', () => {
const mockError = {
response: {
status: 502,
data: { message: 'Service unavailable' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试')
expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data)
})
it('should handle 503 Service Unavailable', () => {
const mockError = {
response: {
status: 503,
data: { message: 'Service unavailable' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试')
expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data)
})
it('should handle 504 Gateway Timeout', () => {
const mockError = {
response: {
status: 504,
data: { message: 'Gateway timeout' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试')
expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data)
})
it('should handle unknown status code', () => {
const mockError = {
response: {
status: 418,
data: { message: 'I am a teapot' },
},
}
const consoleSpy = vi.spyOn(console, 'error')
ApiErrorHandler.handle(mockError)
expect(ElMessage.error).toHaveBeenCalledWith('I am a teapot')
expect(consoleSpy).toHaveBeenCalledWith('Unknown Error:', mockError.response.data)
})
})
})