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

如何使用React Testing Library为Cytoscape编写集成测试?

为Cytoscape编写React集成测试的可行方法

1. Mock Cytoscape库,测试组件交互逻辑

直接测试Canvas渲染的视觉效果难度高,可通过Mock Cytoscape核心库,聚焦测试组件如何调用Cytoscape的API(如节点添加、布局执行等),验证逻辑正确性。

// 测试文件中Mock cytoscape
jest.mock('cytoscape', () => {
  const mockInstance = {
    add: jest.fn(),
    layout: jest.fn(() => ({ run: jest.fn() })),
    nodes: jest.fn(() => ({ length: 2 })),
    edges: jest.fn(() => ({ length: 1 }))
  };
  const mockCytoscape = jest.fn(() => mockInstance);
  mockCytoscape.use = jest.fn();
  return mockCytoscape;
});

// 测试组件初始化逻辑
import { render, screen } from '@testing-library/react';
import CytoscapeGraph from './CytoscapeGraph';
import cytoscape from 'cytoscape';

test('初始化时正确创建实例并添加节点边', () => {
  const testData = {
    nodes: [{ data: { id: 'n1' } }, { data: { id: 'n2' } }],
    edges: [{ data: { source: 'n1', target: 'n2' } }]
  };

  render(<CytoscapeGraph graphData={testData} />);

  expect(cytoscape).toHaveBeenCalled();
  const mockCy = cytoscape.mock.results[0].value;
  
  expect(mockCy.add).toHaveBeenCalledWith([...testData.nodes, ...testData.edges]);
  expect(mockCy.layout().run).toHaveBeenCalled();
});

2. 测试DOM交互触发的Cytoscape行为

模拟用户操作(如点击按钮添加节点),验证组件是否正确调用Cytoscape的对应API。

test('点击添加节点按钮后,实例添加新节点', () => {
  render(<CytoscapeGraph />);
  const mockCy = cytoscape.mock.results[0].value;
  
  screen.getByRole('button', { name: /添加节点/i }).click();
  
  expect(mockCy.add).toHaveBeenCalledWith(expect.arrayContaining([
    expect.objectContaining({ data: expect.objectContaining({ id: expect.any(String) }) })
  ]));
});

3. 直接使用Cytoscape API断言内部状态

在jsdom环境下,无需渲染Canvas即可初始化Cytoscape实例,直接调用API验证节点数量、选中状态等内部逻辑。

test('节点边数量与传入数据一致', () => {
  const testData = {
    nodes: [{ data: { id: 'n1' } }, { data: { id: 'n2' } }],
    edges: [{ data: { source: 'n1', target: 'n2' } }]
  };

  render(<CytoscapeGraph graphData={testData} />);
  const container = screen.getByTestId('cytoscape-container');
  
  // 直接初始化实例(若组件用ref管理,也可通过组件ref获取)
  const cy = cytoscape({
    container,
    elements: [...testData.nodes, ...testData.edges]
  });
  
  expect(cy.nodes().length).toBe(2);
  expect(cy.edges().length).toBe(1);
  
  // 测试节点选中逻辑
  cy.nodes('#n1').select();
  expect(cy.nodes(':selected').length).toBe(1);
});

4. 测试自定义事件回调

验证Cytoscape内部事件(如节点点击)是否正确传递给组件的回调函数。

test('节点点击触发组件的onNodeClick回调', () => {
  const mockOnNodeClick = jest.fn();
  render(<CytoscapeGraph onNodeClick={mockOnNodeClick} />);
  
  const mockCy = cytoscape.mock.results[0].value;
  // 模拟Cytoscape触发节点点击事件
  mockCy.nodes = jest.fn(() => ({
    on: jest.fn((_, handler) => {
      handler({ target: { data: () => ({ id: 'n1' }) } });
    })
  }));
  
  // 重新渲染触发组件内的事件绑定逻辑
  render(<CytoscapeGraph onNodeClick={mockOnNodeClick} />);
  
  expect(mockOnNodeClick).toHaveBeenCalledWith(expect.objectContaining({ id: 'n1' }));
});

注意事项

  • 遵循React-testing-library的理念:优先测试用户可见的行为,而非内部实现细节。
  • 视觉渲染验证需交给端到端测试(如Cypress),集成测试聚焦业务逻辑与API调用正确性。
  • 若组件通过ref管理Cytoscape实例,可利用render的container参数或screen.getByTestId结合ref获取实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:55:23