首页 > 解决方案 > 带有 useState 钩子的 onBlur 在 Jest 中不起作用?

问题描述

我是用反应和玩笑测试代码的新手;开玩笑对钩子有一种奇怪的行为。

这是我的组件。它有 2 个 useState 挂钩,链接到 2 个函数。

只是一个可以正常工作的简单组件。

import React, {useState} from 'react';

export const Test = () => {
  const [cardNumber, setCardNumber] = useState('');
  const [cardType, setCardType] = useState('');

  const handleOnChange = (event) => {
    setCardNumber(event.target.value);
  };

  const handleOnBlur = () => {
    setCardType(cardNumber);
  };

  return (
    <>
      <input type="text" value={cardNumber} onChange={handleOnChange} onBlur={handleOnBlur} />
      <p id="cn">{`CardNumber: ${cardNumber}`}</p>
      <p id="ct">{`CardType: ${cardType}`}</p>
    </>
  );
};

这是测试:

import React from 'react';
import {shallow} from 'enzyme';
import {Test} from '.';
import {act} from 'react-dom/test-utils';

describe('Sandbox Test', () => {
  it('should set cardNumber when doing onChange', async () => {
    const component = shallow(<Test />);

    const inputComponent = component.find('input');
    const value = {target: {value: '123456'}};

    await act(async () => {
      inputComponent.props().onChange(value);
      await component.update();
    });

    const cardNumberComponent = component.find('#cn');
    const cardTypeComponent = component.find('#ct');

    expect(cardNumberComponent.text()).toEqual(`CardNumber: 123456`);
    expect(cardTypeComponent.text()).toEqual(`CardType: `);
  });

  it('should set cardType when doing onBlur', async () => {
    const component = shallow(<Test />);

    const inputComponent = component.find('input');
    const value = {target: {value: '123456'}};

    await act(async () => {
      inputComponent.props().onChange(value);
      inputComponent.props().onBlur();
      await component.update();
    });

    const cardNumberComponent = component.find('#cn');
    const cardTypeComponent = component.find('#ct');

    expect(cardNumberComponent.text()).toEqual(`CardNumber: 123456`);
    expect(cardTypeComponent.text()).toEqual(`CardType: 123456`);
  });
});

我不知道触发 onBlur 动作时发生了什么(我知道它已被触发),但不知何故,它不会触发 setCardType(); 因此,这是我在运行测试时遇到的错误:

测试时控制台错误

我究竟做错了什么?在过去的几个小时里一直在尝试调试这个,我真的不知道该怎么做。

标签: javascriptreactjsunit-testingtestingjestjs

解决方案


我认为调用会.udpate()使用所有更新的数据重新创建节点树,但不会自动更新对您获得的节点的引用find()。因此,inputComponent您模拟onBlur事件的那一刻是第一次渲染的实例,该实例使用旧版本的onBlur处理程序,cardNumber状态为空值。在触发事件之前,您需要再次获取输入节点以获取更新的实例onBlur

    ...
    let inputComponent = component.find("input"); 
    const value = { target: { value: "123456" } };

    await act(async () => {
      inputComponent.props().onChange(value);
      await component.update();
      inputComponent = component.find("input");
      inputComponent.props().onBlur();
      await component.update();
    });
    ...

https://codesandbox.io/s/input-onchange-onblur-enzyme-kdg0u?file=/src/MyComponent.test.tsx


推荐阅读