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

Jest测试React输入与按钮点击报错求助:找不到对应节点

Fixing "Method 'props' is only meant to be run on a single node. 0 found instead." in FITB Component Tests

Hey there! Let's break down why your Jest tests are throwing that error and how to fix it step by step.

What's Causing the Error?

That error pops up because when you try to run .simulate('change') on .fitb-input, Enzyme can't find any matching input elements. Here's the root cause:

  • Your FITB component initializes splitList (which drives input rendering) in componentDidMount using data from this.props.messages.
  • In your test setup, you're rendering the component without passing the required messages prop:
    component = shallow(<FITB onReply={mockFn} />);
    
  • Without messages, splitList stays empty, so no <input className="fitb-input"> elements are rendered. When you call component.find('.fitb-input'), it returns 0 nodes—hence the error.

Step-by-Step Fixes

1. Pass Valid messages Prop to the Component

First, give the component the data it needs to render input fields. Create a mock messages array with a FILL_IN_THE_BLANK entry:

const mockMessages = [
  {
    type: 'FILL_IN_THE_BLANK',
    message: 'Hello ____ World'
  }
];

Update your beforeEach to include this prop:

beforeEach(() => {
  component = shallow(<FITB onReply={mockFn} messages={mockMessages} />);
});

2. Fix the Input Change Test

Your current test has two key issues:

  • You're expecting inputList (an array) to equal a full string—this is a mismatch in state structure.
  • The onInputChange is a curried function, but Enzyme handles this correctly once the input exists.

Here's the corrected test:

test('Should update input state and validity on change', () => {
  const input = component.find('.fitb-input').first();
  
  // Test valid input
  input.simulate('change', { target: { value: 'Beautiful' } });
  expect(component.state().inputList[0]).toEqual('Beautiful');
  expect(component.state().isValid).toEqual(true);
  
  // Test invalid input (non-ASCII character fails the regex)
  input.simulate('change', { target: { value: 'Béautiful' } });
  expect(component.state().isValid).toEqual(false);
});

3. Fix the Button Click Test

The send button is disabled until inputs are valid. You need to fill the inputs first to trigger onReply:

test('Should call onReply when send button is clicked with valid inputs', () => {
  // Fill the input
  const input = component.find('.fitb-input').first();
  input.simulate('change', { target: { value: 'Beautiful' } });
  
  // Verify button is enabled
  const button = component.find('.btn-info-dm');
  expect(button.prop('disabled')).toEqual(false);
  
  // Simulate click and check onReply was called
  button.simulate('click');
  expect(mockFn).toHaveBeenCalledWith('Hello Beautiful World');
});

Full Corrected Test File

Here's the complete test file with all fixes:

import React from 'react';
import FITB from '../components/dialogManager/fitb';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';

describe('FITB', () => {
  let component;
  const mockFn = jest.fn();
  const mockMessages = [
    {
      type: 'FILL_IN_THE_BLANK',
      message: 'Hello ____ World'
    }
  ];

  beforeEach(() => {
    component = shallow(<FITB onReply={mockFn} messages={mockMessages} />);
  });

  test('Should initialize the FITB content', () => {
    expect(component.find('.rply-block')).toHaveLength(1);
  });

  test('Should call onReply when send button is clicked with valid inputs', () => {
    const input = component.find('.fitb-input').first();
    input.simulate('change', { target: { value: 'Beautiful' } });
    
    const button = component.find('.btn-info-dm');
    button.simulate('click');
    
    expect(mockFn).toHaveBeenCalledWith('Hello Beautiful World');
  });

  test('Should update input state and validity on change', () => {
    const input = component.find('.fitb-input').first();
    
    input.simulate('change', { target: { value: 'Beautiful' } });
    expect(component.state().inputList[0]).toEqual('Beautiful');
    expect(component.state().isValid).toEqual(true);
    
    input.simulate('change', { target: { value: 'Béautiful' } });
    expect(component.state().isValid).toEqual(false);
  });
});

Additional Notes

  • Always ensure your component has all required props during testing—most rendering issues stem from missing expected data.
  • Double-check state structures (like inputList being an array) to avoid incorrect test expectations.
  • For components relying on componentDidMount to initialize state, shallow rendering works fine here, but use mount if you need to test interactions with child components.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:09:57