javascript - 在useEffect()中状态更改后酶mount()重新渲染?
问题描述
我是 React 和 React 单元测试的新手。我有一个组件,它根据使用状态设置的状态加载一些 div。在 useEffect 中,如果一个函数返回一个被拒绝的 promise,那么应该显示一个错误 div。我想测试这个场景,但是因为初始状态设置为 error = false,所以仍然显示原始 div。
我的问题是,我该怎么做才能让测试注册更新的 div?我正在使用 Enzyme 的 mount(),但我也尝试过使用 shallow()。我还验证了它实际上是通过一些 console.logs 进入 .catch() 的。
零件:
export const Main = (props) => {
const [showLoadError, setShowLoadError] = useState(false);
const [loadError, setLoadError] = useState('');
React.useEffect(() => {
const { categories, actions } = props;
// retrieve categories from Db if they don't exist in state
if (categories.length === 0) {
actions.loadCategories().catch(err => {
setShowLoadError(true);
setLoadError(err.message);
})
} else {
setShowLoadError(false);
setLoadError('');
}
}, []);
return (
<>
{/* conditional show for error container if loading failed */}
{showLoadError &&
<div className="load-error">
Error loading categories. {loadError}
</div>
}
{/* conditional show for no Load error */}
{!showLoadError &&
<div className="grid-container grid-container--fit">
<div><CategoryContainer /></div>
<div><ItemContainer /></div>
<div><FileAssociationsContainer /></div>
</div>
}
</>
);
}
测试:
import React from 'react';
import ConnectedApp, { Main } from './Main';
import { shallow, mount } from 'enzyme';
jest.mock("../category/CategoryContainer");
jest.mock("../item/ItemContainer");
jest.mock("../fileAssociations/FileAssociationsContainer");
describe("Main component", () => {
beforeEach(() => {
fetch.resetMocks()
});
test('should render error div after loadCategories fail', () => {
const categories = [];
const errMessage = {message: 'test error'}
const actions = {
loadCategories: jest.fn(() => {
return Promise.reject(errMessage);
})
};
const wrapper = mount(<Main categories={categories} actions={actions} />);
wrapper.setProps(); // rerenders
// expect there to be a load-error div
expect(wrapper.find('div').hasClass('load-error')).toBe(true)
// expect loadCategories to be called because component was passed in empty categories
expect(actions.loadCategories).toBeCalled();
});
});
我已经尝试过了wrapper.setProps()
,wrapper.update()
在我没有运气之前。
此外,这个单元测试给出了一个开玩笑的警告,即An update to Main inside a test was not wrapped in act(...)
. 仅当 actions.loadCategories() 返回拒绝的承诺时才会发生这种情况。当它返回一个已解决的承诺时,它不会这样做。我尝试将代码移动到 act() 中,但没有成功删除错误,如下所示:
act(() => {
actions = {
loadCategories: jest.fn(() => {
return Promise.reject(errMessage);
})
};
wrapper = mount(<Main categories={categories} actions={actions} />);
wrapper.setProps(); // rerenders
});
解决方案
推荐阅读
- jquery - 表 TD Rowspan 不适用于 Ajax Jquery
- dspace - 如何在 DSpace 的集合中创建虚拟集?
- jsoup - JSoup 无法从 Google 购物中抓取图像 URL
- python - Python KeyError:'flags',运行 BlueBorne 脚本时
- react-native - react-native SectionList 如何使用scrollToLocation滚动到顶部?
- python - 来自不同分布的python采样
- java - API设计建议
- docker - 如果“docker-compose 创建的容器无法使用外部机密”,推荐的构建方法是什么?
- angular - 你好!我最近正在尝试使用 nativescript+angular
- javascript - getting vue child component target of parent component event