Angular xlsx格式文件上传方法单元测试用例编写求助
Angular 文件上传单元测试实现方案
现有测试存在的问题
你当前的测试代码直接传入字符串作为参数调用onFileUpload,不符合该方法要求传入文件选择事件对象的入参要求,同时没有mock FileReader、XLSX相关依赖,也没有处理异步的setTimeout逻辑,无法覆盖全部分支代码。
完整实现代码
前置依赖准备
在测试文件的顶部导入所需测试工具:
import { fakeAsync, tick } from '@angular/core/testing'; import * as XLSX from 'xlsx';
单测用例实现
需要覆盖两个分支场景:文件数据行数≤20、文件数据行数>20
// 通用mock事件生成方法 function createFileUploadEvent(fileName: string, fileContent: string): Event { const file = new File([fileContent], fileName, { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const dataTransfer = new DataTransfer(); dataTransfer.items.add(file); const input = document.createElement('input'); input.type = 'file'; input.files = dataTransfer.files; return new Event('change', { target: input }); } it('上传行数≤20的Excel文件时应正常解析且提示成功', fakeAsync(() => { // 1. Mock XLSX相关方法,返回小于等于20行的模拟数据 const mockData = new Array(10).fill(['测试列1', '测试列2']); spyOn(XLSX, 'read').and.returnValue({ SheetNames: ['Sheet1', 'Sheet2'], Sheets: { 'Sheet2': {} as XLSX.WorkSheet } } as XLSX.WorkBook); spyOn(XLSX.utils, 'sheet_to_json').and.returnValue(mockData); // 2. 构造mock事件并触发方法 const mockEvent = createFileUploadEvent('Upload.xlsx', 'mock excel binary content'); component.onFileUpload(mockEvent); fixture.detectChanges(); // 3. 校验同步逻辑结果 expect(component.sheetJsExcelName).toBe('Upload.xlsx'); expect(component.data.length).toBe(10); expect(component.data.length).toBeLessThanOrEqual(20); expect(component.errorMsg).toBe(''); // 4. 处理setTimeout异步逻辑,校验成功提示 tick(5000); fixture.detectChanges(); expect(component.successMsg).toBe('Upload.xlsx is uploaded succesfully'); })); it('上传行数>20的Excel文件时应提示超出上限', () => { // 1. Mock XLSX相关方法,返回超过20行的模拟数据 const mockData = new Array(21).fill(['测试列1', '测试列2']); spyOn(XLSX, 'read').and.returnValue({ SheetNames: ['Sheet1', 'Sheet2'], Sheets: { 'Sheet2': {} as XLSX.WorkSheet } } as XLSX.WorkBook); spyOn(XLSX.utils, 'sheet_to_json').and.returnValue(mockData); // 2. 构造mock事件并触发方法 const mockEvent = createFileUploadEvent('OverSize.xlsx', 'mock excel binary content'); component.onFileUpload(mockEvent); fixture.detectChanges(); // 3. 校验结果 expect(component.sheetJsExcelName).toBe('OverSize.xlsx'); expect(component.data.length).toBe(21); expect(component.errorMsg).toBe('Record limit is exceeding'); expect(component.successMsg).toBe(''); });
补充说明
- 用
fakeAsync和tick处理5秒延时的成功提示逻辑,不需要真实等待5秒即可完成测试 - 所有外部依赖XLSX的方法都通过spyOn mock,不需要依赖真实的Excel文件解析能力
- 构造了符合真实DOM事件规范的文件选择事件,完全模拟用户实际选择文件的交互场景
- 两个用例覆盖了所有分支逻辑,可实现100%代码覆盖率
内容的提问来源于stack exchange,提问作者precherla
相关产品推荐
相关产品推荐

