Angular Jest单元测试文件上传输入报错:DataTransfer未定义
Jest单元测试模拟文件上传:解决DataTransfer未定义问题
问题原因
Jest默认依赖的jsdom环境并未内置DataTransfer的完整实现,这就是你遇到"DataTransfer is not defined"错误的核心原因。
解决方案
以下是几种可行的替代方案,无需依赖DataTransfer即可完成文件上传的模拟:
方案1:直接构造FileList对象
input元素的files属性本质是FileList类型,我们可以直接构造该对象绕开DataTransfer:
function selectFile(inputElement: HTMLInputElement) { const mockFile = new File(['Hello World'], 'test-file.txt'); // 手动构造符合FileList接口的对象 const fileList = Object.assign(new FileList(), { 0: mockFile, length: 1, item: (index: number) => index === 0 ? mockFile : null }); inputElement.files = fileList; inputElement.dispatchEvent(new Event('change')); return fixture.whenStable(); }
方案2:全局模拟DataTransfer实现
如果希望保留原有代码结构,可以在测试文件顶部或Jest的全局setup文件中添加DataTransfer的模拟类:
// 模拟DataTransfer类 class MockDataTransfer { private _items: File[] = []; public files: FileList; constructor() { // 初始化符合FileList规范的files属性 this.files = Object.assign(new FileList(), { get length() { return this._items.length; }, item: (index: number) => this._items[index] || null }); } // 模拟items.add方法 add(item: File) { this._items.push(item); } } // 将模拟类挂载到全局对象 global.DataTransfer = MockDataTransfer as typeof DataTransfer;
添加后,你原来的selectFile函数即可正常运行。
方案3:升级jsdom版本(可选)
部分较旧版本的jsdom确实未实现DataTransfer,可以尝试升级jsdom到最新稳定版,不过这种方式可能会引入其他依赖变更,不如前两种方案直接可控。
额外注意
文件上传触发的change事件属于普通Event类型,使用new Event('change')比InputEvent更贴合实际场景。
内容的提问来源于stack exchange,提问作者Cody Pritchard
相关产品推荐
相关产品推荐

