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

使用Jest测试ReactJS组件异步渲染:验证子组件按数据渲染

Testing React 16.2 Component to Verify SubComponent Render Count

Let's break down how to write this test step by step. First, I'll assume your component fetches the data array (either synchronously or asynchronously) and renders a SubComponent for each item—here's how to validate that behavior with Jest and React Testing Library (which works great with React 16.2).

Step 1: Mock the External Library

First, we need to mock externalLibrary so its doStuff() method returns our controlled 3-item array. This ensures our test doesn't depend on real external behavior.

// At the top of your test file
import React from 'react';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
import externalLibrary from 'external-library';

// Mock the entire external library
jest.mock('external-library', () => ({
  doStuff: jest.fn(() => [
    { id: 1, label: 'First Item' },
    { id: 2, label: 'Second Item' },
    { id: 3, label: 'Third Item' }
  ])
}));

Step 2: Write the Test Case

We'll cover two common scenarios: synchronous data loading and asynchronous data loading (since you mentioned React's async test examples, this covers both cases).

Scenario 1: Synchronous Data Loading

If your component sets state immediately after calling doStuff() (e.g., in componentDidMount), the test can directly query the rendered components:

describe('MyComponent', () => {
  it('renders one SubComponent for each item in the data array', () => {
    // Render the component
    render(<MyComponent />);

    // Get all instances of SubComponent using a test ID (add this to your SubComponent!)
    // In SubComponent.jsx, add: <div data-testid="sub-component">...</div>
    const subComponents = screen.getAllByTestId('sub-component');

    // Verify we have exactly 3 SubComponents
    expect(subComponents).toHaveLength(3);

    // Optional: Verify each item's content is rendered (if relevant)
    expect(screen.getByText('First Item')).toBeInTheDocument();
    expect(screen.getByText('Second Item')).toBeInTheDocument();
    expect(screen.getByText('Third Item')).toBeInTheDocument();
  });
});

Scenario 2: Asynchronous Data Loading

If doStuff() returns a Promise (common for API calls), we need to wait for the component to update after resolving the Promise. Use async/await with Testing Library's findBy* or findAllBy* methods, which automatically wait for elements to appear:

it('renders SubComponents after async data loads', async () => {
  // Override the mock to return a Promise instead
  externalLibrary.doStuff.mockResolvedValue([
    { id: 1, label: 'Async Item 1' },
    { id: 2, label: 'Async Item 2' },
    { id: 3, label: 'Async Item 3' }
  ]);

  render(<MyComponent />);

  // Wait for all SubComponents to render
  const subComponents = await screen.findAllByTestId('sub-component');
  expect(subComponents).toHaveLength(3);

  // Verify async content
  expect(await screen.findByText('Async Item 1')).toBeInTheDocument();
});

Key Notes

  • Add a test ID to SubComponent: Using data-testid is a stable way to query components without relying on text or CSS classes that might change.
  • React Testing Library vs Enzyme: Testing Library is recommended here because it focuses on user-centric testing (what the user sees) rather than implementation details, which aligns with your goal of verifying the final render result.
  • React 16.2 Compatibility: React Testing Library supports React 16.0+, so this works perfectly with your version.

Example SubComponent

Just to make sure the test ID makes sense, here's a simple SubComponent implementation:

// SubComponent.jsx
import React from 'react';

const SubComponent = ({ item }) => {
  return (
    <div data-testid="sub-component">
      {item.label}
    </div>
  );
};

export default SubComponent;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:34:20