[英]"setProps()" not triggering "useEffect" in Jest
當我在測試用例中更新功能組件的道具時,它不會觸發 useEffect。 但是它正在更新 myComp 中的道具。
組件示例:
const myComp = ({userId, myAction}) => {
useEffect(() => {
myAction(userId);
}, [userId]);
return <div>Test</div>
}
測試用例示例:
.....
describe('Testing MyComp', () => {
it('should call myAction with userID', () => {
const userId = 'testId';
wrapper.setProps({userId});
expect(myAction).toHaveBeenCalledWith(userId);
});
});
在 React 淺層渲染器中不會調用useEffect()
和useLayoutEffect()
。 請參閱組件淺渲染時未調用 useEffect和此問題。
您應該使用mount
function。
例如
index.tsx
:
import React, { useEffect } from 'react';
export const MyComp = ({ userId, myAction }) => {
useEffect(() => {
myAction(userId);
}, [userId]);
return <div>Test</div>;
};
index.test.tsx
:
import React from 'react';
import { mount } from 'enzyme';
import { MyComp } from './';
describe('67312763', () => {
it('should pass', () => {
const props = {
userId: '1',
myAction: jest.fn(),
};
const wrapper = mount(<MyComp {...props} />);
expect(props.myAction).toHaveBeenCalledWith('1');
const userId = '2';
wrapper.setProps({ userId });
expect(props.myAction).toHaveBeenCalledWith('2');
});
});
測試結果:
PASS examples/67312763/index.test.tsx (7.221 s)
67312763
✓ should pass (31 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.tsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 7.731 s
package 版本:
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"jest": "^26.6.3",
"jest-enzyme": "^7.1.2",
"react": "^16.14.0",
@slideshowp2 上面的答案是正確的,但是如果您像我一樣發現setProps
即使您使用 mount 仍然無法正常工作,這可能對您有用。
React 可能會將來自多個setState()
調用的 state 更新批處理到單個更新中( 檢查一下),這可能是異步的。 那么期望 get 被觸發,但 setState 還沒有運行(因為它在等待運行的 JS 事件循環中),並且您的測試失敗。
您可能會問如何避免這種情況? 將您的期望包裝在setTimeout
中,因此它最終會出現在同一個異步位置,並將在setState
之后運行!
像這樣的東西:
describe('Testing MyComp', () => {
it('should call myAction with userID', () => {
const userId = 'testId';
wrapper.setProps({userId});
setTimeout(() => {
expect(myAction).toHaveBeenCalledWith(userId);
}, 0)
});
});
另外,請注意,我不喜歡這樣,但它確實有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.