You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构造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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:06:05