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

使用react-testing-library测试@dnd-kit拖拽功能时基础事件未触发

解决@dnd-kit拖拽测试中核心事件不触发的问题

针对@dnd-kit拖拽测试时onDragStart/onDragMove/onDragOver/onDragEnd等核心事件不触发的问题,以下是几个可行的解决方案:

1. 使用@testing-library/user-event替代fireEvent

fireEvent是低级事件触发工具,无法模拟真实用户拖拽时的完整事件序列和交互逻辑。user-event更贴近真实用户行为,能正确触发@dnd-kit依赖的pointer事件链。

示例代码:

import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('验证元素拖拽功能', async () => {
  const user = userEvent.setup();
  const dragSource = screen.getByTestId('draggable-item-1');
  const dropTarget = screen.getByTestId('draggable-item-3');

  // 模拟完整拖拽流程:按住 → 拖动到目标 → 松开
  await user.pointer({
    target: dragSource,
    keys: '[MouseLeft]', // 按住鼠标左键
    moveTo: dropTarget,
  });

  // 这里添加业务断言,比如验证元素顺序是否变化
  expect(screen.getAllByTestId(/draggable-item-/)).toHaveLength(3);
  // ...其他自定义断言
});

如果需要更细粒度的控制,可以拆分步骤:

await user.pointerDown(dragSource);
await user.pointerMove(dropTarget, { clientX: 200, clientY: 200 }); // 指定拖动坐标
await user.pointerUp();

2. 确保测试环境支持Pointer Events

@dnd-kit基于Pointer Events实现拖拽,部分测试环境(如jsdom)默认未完全启用该特性,需要手动配置。

Jest配置示例(jest.config.js):

module.exports = {
  testEnvironmentOptions: {
    jsdom: {
      features: {
        PointerEvent: true,
      },
    },
  },
};

3. 给fireEvent补充必要的事件参数

如果坚持使用fireEvent,需要为拖拽事件传递dataTransfer对象(@dnd-kit内部依赖该对象处理拖拽状态),且要保证事件顺序和参数正确。

修正后的fireEvent示例:

import { fireEvent } from '@testing-library/react';

// 初始化mock的dataTransfer
const mockDataTransfer = {
  setData: jest.fn(),
  getData: jest.fn(),
  dropEffect: 'move',
  effectAllowed: 'move',
};

const firstItem = screen.getByTestId('drag-item-0');
const lastItem = screen.getByTestId('drag-item-2');

// 按顺序触发事件,每个事件都传递dataTransfer
fireEvent.dragStart(firstItem, { dataTransfer: mockDataTransfer });
fireEvent.dragEnter(lastItem, { dataTransfer: mockDataTransfer });
fireEvent.dragOver(lastItem, { dataTransfer: mockDataTransfer });
fireEvent.drop(lastItem, { dataTransfer: mockDataTransfer });
fireEvent.dragEnd(firstItem, { dataTransfer: mockDataTransfer });

4. 检查组件的拖拽触发条件

  • 确认Draggable组件已正确设置id属性,且未被设置disabled状态;
  • 部分场景下,拖拽元素需要先获得焦点,可在测试前添加await user.click(dragSource)确保元素处于可交互状态。

内容的提问来源于stack exchange,提问作者ThiwankaB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:26:15