我是React和React单元测试的新手。我有一个基于useState设置的状态加载一些div的组件。在useEffect内部,如果从函数返回了被拒绝的Promise,则应显示错误div。我想测试这种情况,但是因为初始状态设置为error = false,所以仍然显示原始div。
我的问题是,我该怎么做才能使测试注册更新的div?我正在使用Enzyme的mount(),但我也尝试使用了deep()。我还验证了它是否实际上已通过一些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
});