- 修复路由守卫:未登录时直接跳转,不显示提示信息 - 修复API拦截器:401错误直接跳转,无需确认 - 移除不必要的ElMessageBox确认框 - 优化Token过期处理逻辑 - 修复文件管理API引入路径和URL前缀 - 修复调拨/回收管理API端点不匹配问题 - 修复通知管理API方法不匹配问题 - 统一系统配置API路径为单数形式 影响文件: - src/router/index.ts - src/api/request.ts - src/api/file.ts - src/api/index.ts 测试状态: - 前端构建通过 - 所有API路径已验证 - 登录流程测试通过 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
340 lines
7.4 KiB
TypeScript
340 lines
7.4 KiB
TypeScript
/**
|
|
* 资产列表组件测试
|
|
*
|
|
* 测试内容:
|
|
* - 组件渲染
|
|
* - 数据加载
|
|
* - 搜索功能
|
|
* - 分页功能
|
|
* - 事件触发
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { mount, VueWrapper } from '@vue/test-utils'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import ElementPlus from 'element-plus'
|
|
import AssetList from '@/views/assets/AssetList.vue'
|
|
import * as assetApi from '@/api/assets'
|
|
|
|
// Mock API模块
|
|
vi.mock('@/api/assets', () => ({
|
|
getAssetList: vi.fn(),
|
|
deleteAsset: vi.fn(),
|
|
getAssetStatistics: vi.fn()
|
|
}))
|
|
|
|
describe('AssetList组件', () => {
|
|
let wrapper: VueWrapper<any>
|
|
let pinia: any
|
|
|
|
beforeEach(() => {
|
|
// 创建新的Pinia实例
|
|
pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
|
|
// Mock API响应
|
|
vi.mocked(assetApi.getAssetList).mockResolvedValue({
|
|
items: [
|
|
{
|
|
id: 1,
|
|
assetCode: 'ASSET-20250124-0001',
|
|
assetName: '联想台式机',
|
|
deviceType: { id: 1, typeName: '计算机' },
|
|
organization: { id: 1, orgName: '天河网点' },
|
|
status: 'in_use',
|
|
purchaseDate: '2024-01-15',
|
|
purchasePrice: 4500.00
|
|
}
|
|
],
|
|
total: 1,
|
|
page: 1,
|
|
pageSize: 20
|
|
})
|
|
|
|
vi.mocked(assetApi.getAssetStatistics).mockResolvedValue({
|
|
totalCount: 100,
|
|
totalValue: 500000.00,
|
|
statusDistribution: {
|
|
in_stock: 30,
|
|
in_use: 50,
|
|
maintenance: 10,
|
|
scrapped: 10
|
|
}
|
|
})
|
|
})
|
|
|
|
afterEach(() => {
|
|
if (wrapper) {
|
|
wrapper.unmount()
|
|
}
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('应该正确渲染组件', () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-pagination': true,
|
|
'el-input': true,
|
|
'el-button': true
|
|
}
|
|
}
|
|
})
|
|
|
|
expect(wrapper.find('.asset-list').exists()).toBe(true)
|
|
})
|
|
|
|
it('应该在挂载时加载资产列表', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-pagination': true
|
|
}
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.$nextTick()
|
|
|
|
expect(assetApi.getAssetList).toHaveBeenCalledWith({
|
|
page: 1,
|
|
page_size: 20
|
|
})
|
|
})
|
|
|
|
it('应该显示资产统计数据', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-statistic': true
|
|
}
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.$nextTick()
|
|
await wrapper.vm.$nextTick() // 等待统计数据加载
|
|
|
|
expect(assetApi.getAssetStatistics).toHaveBeenCalled()
|
|
})
|
|
|
|
it('应该支持搜索功能', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-input': true,
|
|
'el-button': true
|
|
}
|
|
}
|
|
})
|
|
|
|
const searchKeyword = '联想'
|
|
wrapper.vm.searchKeyword = searchKeyword
|
|
await wrapper.vm.handleSearch()
|
|
|
|
expect(assetApi.getAssetList).toHaveBeenCalledWith({
|
|
page: 1,
|
|
page_size: 20,
|
|
keyword: searchKeyword
|
|
})
|
|
})
|
|
|
|
it('应该支持分页功能', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-pagination': true
|
|
}
|
|
}
|
|
})
|
|
|
|
wrapper.vm.pagination.page = 2
|
|
await wrapper.vm.fetchAssets()
|
|
|
|
expect(assetApi.getAssetList).toHaveBeenCalledWith({
|
|
page: 2,
|
|
page_size: 20
|
|
})
|
|
})
|
|
|
|
it('应该触发刷新事件', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-button': true
|
|
}
|
|
}
|
|
})
|
|
|
|
const refreshSpy = vi.spyOn(wrapper.vm, 'fetchAssets')
|
|
await wrapper.vm.handleRefresh()
|
|
|
|
expect(refreshSpy).toHaveBeenCalled()
|
|
})
|
|
|
|
it('应该打开创建对话框', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-button': true,
|
|
'asset-create-dialog': true
|
|
}
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.openCreateDialog()
|
|
expect(wrapper.vm.createDialogVisible).toBe(true)
|
|
})
|
|
|
|
it('应该打开编辑对话框', async () => {
|
|
const mockAsset = {
|
|
id: 1,
|
|
assetCode: 'ASSET-20250124-0001',
|
|
assetName: '联想台式机'
|
|
}
|
|
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'asset-edit-dialog': true
|
|
}
|
|
}
|
|
})
|
|
|
|
await wrapper.vm.openEditDialog(mockAsset)
|
|
expect(wrapper.vm.editDialogVisible).toBe(true)
|
|
expect(wrapper.vm.currentAsset).toEqual(mockAsset)
|
|
})
|
|
|
|
it('应该删除资产', async () => {
|
|
vi.mocked(assetApi.deleteAsset).mockResolvedValue({})
|
|
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-button': true
|
|
}
|
|
}
|
|
})
|
|
|
|
// Mock确认对话框
|
|
vi.spyOn(wrapper.vm as any, '$confirm').mockResolvedValue('confirm')
|
|
|
|
await wrapper.vm.handleDelete(1)
|
|
|
|
expect(assetApi.deleteAsset).toHaveBeenCalledWith(1)
|
|
})
|
|
|
|
it('应该在搜索时重置页码', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-input': true
|
|
}
|
|
}
|
|
})
|
|
|
|
wrapper.vm.pagination.page = 5
|
|
wrapper.vm.searchKeyword = '测试'
|
|
await wrapper.vm.handleSearch()
|
|
|
|
expect(wrapper.vm.pagination.page).toBe(1)
|
|
})
|
|
|
|
it('应该显示加载状态', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true
|
|
}
|
|
}
|
|
})
|
|
|
|
wrapper.vm.loading = true
|
|
await wrapper.vm.$nextTick()
|
|
|
|
expect(wrapper.find('.loading').exists()).toBe(true)
|
|
})
|
|
|
|
it('应该处理API错误', async () => {
|
|
vi.mocked(assetApi.getAssetList).mockRejectedValue(new Error('网络错误'))
|
|
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true
|
|
}
|
|
}
|
|
})
|
|
|
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
|
|
await wrapper.vm.fetchAssets()
|
|
|
|
expect(consoleSpy).toHaveBeenCalled()
|
|
consoleSpy.mockRestore()
|
|
})
|
|
|
|
it('应该支持状态筛选', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-select': true
|
|
}
|
|
}
|
|
})
|
|
|
|
wrapper.vm.filters.status = 'in_use'
|
|
await wrapper.vm.handleFilter()
|
|
|
|
expect(assetApi.getAssetList).toHaveBeenCalledWith({
|
|
page: 1,
|
|
page_size: 20,
|
|
status: 'in_use'
|
|
})
|
|
})
|
|
|
|
it('应该支持设备类型筛选', async () => {
|
|
wrapper = mount(AssetList, {
|
|
global: {
|
|
plugins: [pinia, ElementPlus],
|
|
stubs: {
|
|
'el-table': true,
|
|
'el-select': true
|
|
}
|
|
}
|
|
})
|
|
|
|
wrapper.vm.filters.deviceTypeId = 1
|
|
await wrapper.vm.handleFilter()
|
|
|
|
expect(assetApi.getAssetList).toHaveBeenCalledWith({
|
|
page: 1,
|
|
page_size: 20,
|
|
device_type_id: 1
|
|
})
|
|
})
|
|
})
|