如何构造CdkDragDrop事件模拟入参用于Angular+Jest单元测试
单元测试实现方案
完全可以构造CdkDragDrop<string[]>类型的模拟载荷作为入参,直接调用drop方法完成单元测试,无需触发真实的拖拽交互。
实现步骤
- 预先初始化组件的
formCtrls数组、mockIDGenerator方法的返回值,也可以根据需要mock@angular/cdk/drag-drop提供的moveItemInArray方法方便调用验证。 - 针对方法的两个逻辑分支(同容器排序、跨容器新增),分别构造对应的模拟
CdkDragDrop对象即可。
Jest测试示例代码
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; // 替换为你自己的组件导入路径 import { YourComponent } from './your.component'; // mock cdk提供的排序工具方法,方便后续验证调用 jest.mock('@angular/cdk/drag-drop', () => ({ ...jest.requireActual('@angular/cdk/drag-drop'), moveItemInArray: jest.fn() })); describe('YourComponent', () => { let component: YourComponent; beforeEach(() => { component = new YourComponent(); // 初始化formCtrls的测试初始值 component.formCtrls = [ { paramId: 'test_0', name: '控件1' }, { paramId: 'test_1', name: '控件2' } ]; // mock IDGenerator方法返回固定值,避免随机值干扰测试 jest.spyOn(component, 'IDGenerator').mockReturnValue('mock_generated_id'); }); // 测试同容器内拖拽排序分支 it('同容器拖拽时应该执行排序逻辑并设置选中控件', () => { // 构造仅包含方法用到属性的模拟event const mockEvent = { previousContainer: { data: component.formCtrls }, container: { data: component.formCtrls }, previousIndex: 0, currentIndex: 1 } as CdkDragDrop<string[]>; component.drop(mockEvent); // 验证排序方法被正确调用 expect(moveItemInArray).toHaveBeenCalledWith(component.formCtrls, 0, 1); // 验证选中控件设置符合预期 expect(component.selectedControl).toBe(component.formCtrls[1]); }); // 测试跨容器拖拽新增分支 it('跨容器拖拽时应该克隆数据并插入到指定位置', () => { const mockOriginItemData = { paramId: 'origin_param_id', name: '新增控件' }; const mockEvent = { previousContainer: { data: [] }, container: { data: component.formCtrls }, item: { data: mockOriginItemData }, previousIndex: 0, currentIndex: 1 } as CdkDragDrop<string[]>; component.drop(mockEvent); // 验证formCtrls长度增加1 expect(component.formCtrls.length).toBe(3); // 验证插入位置、克隆数据、paramId生成符合预期 const insertedItem = component.formCtrls[1]; expect(insertedItem.name).toBe('新增控件'); expect(insertedItem.paramId).toBe('mock_generated_id_1'); // 验证选中控件为新插入的项 expect(component.selectedControl).toBe(insertedItem); }); });
注意事项
- 构造模拟对象时用
as CdkDragDrop<string[]>做类型断言即可满足TS类型校验,不需要补全CdkDragDrop的所有原生属性,只需要传入方法中实际用到的属性即可。 - 如果你的
formCtrls是Angular表单的FormArray实例,可以提前构造好模拟的FormArray实例再赋值给组件属性。
内容的提问来源于stack exchange,提问作者raju
相关产品推荐
相关产品推荐

