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
FITBcomponent initializessplitList(which drives input rendering) incomponentDidMountusing data fromthis.props.messages. - In your test setup, you're rendering the component without passing the required
messagesprop:component = shallow(<FITB onReply={mockFn} />); - Without
messages,splitListstays empty, so no<input className="fitb-input">elements are rendered. When you callcomponent.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
onInputChangeis 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
inputListbeing an array) to avoid incorrect test expectations. - For components relying on
componentDidMountto initialize state, shallow rendering works fine here, but usemountif you need to test interactions with child components.
内容的提问来源于stack exchange,提问作者user2119252
相关产品推荐
相关产品推荐

