簡體   English   中英

帶有 useState 鈎子的 onBlur 在 Jest 中不起作用?

[英]onBlur with useState hook not working in Jest?

我是用 react 和 jest 測試代碼的新手; 和 jest 對鈎子有一種奇怪的行為。

這是我的組件。 它有 2 個 useState 鈎子,鏈接到 2 個函數。

  • HandleChange 將通過 onChange 觸發,並使用 setCardNumber() 設置 cardNumber。
  • HandleBlur 將使用 onBlur 觸發,並使用 setCardType() 設置 cardType。

只是一個可以正常工作的簡單組件。

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(); 因此,這是我在運行測試時遇到的錯誤:

測試時控制台錯誤

我究竟做錯了什么? 在過去的幾個小時里一直試圖調試這個,我真的不知道該怎么做。

我認為對.udpate()的調用使用所有更新的數據重新創建節點樹,但不會自動更新對使用find()獲得的節點的引用。 因此,當您模擬onBlur事件時,您擁有的inputComponent是第一次渲染的實例,使用舊版本的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

我認為這是因為您在同一塊act()中調用.onChange().onBlur() act() 所以onChangeonBlur都在同一個cardType變量上使用閉包運行,並且只有在該組件使用更新的cardType重新渲染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);
      await component.update();
    });

    await act(async () => {
      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`);
  });

另外,我不確定您是否真的需要await act()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM