[英]onBlur with useState hook not working in Jest?
我是用 react 和 jest 測試代碼的新手; 和 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(); 因此,這是我在運行測試時遇到的錯誤:
我究竟做錯了什么? 在過去的幾個小時里一直試圖調試這個,我真的不知道該怎么做。
我認為對.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()
。 所以onChange
和onBlur
都在同一個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.