我想写一个单元测试,以确保我的用于修改用户密码的组件在 onSubmit
当表单被提交时。还有其他几个测试使用了与此相同的方法,但它们都通过了,并给出了相同的错误。
这是其中一个测试。
import { act } from "react-dom/test-utils";
it("should render an Alert component if password and confirmPassword do not match", async () => {
global.scrollTo = jest.fn();
const wrapper = mount(
<Provider store={reduxStore}>
<Router>
<ChangePassword />
</Router>
</Provider>
);
pwFuncs.checkCurrentPassword = jest.fn(() => true);
pwFuncs.comparePW = jest.fn(() => false);
const fakeEvent = {
preventDefault: () => console.log("Prevent default..."),
};
wrapper
.find("input")
.at(0)
.simulate("change", {
target: { name: "currentPassword", value: "password1234" },
});
wrapper
.find("input")
.at(1)
.simulate("change", {
target: { name: "newPassword", value: "1234drowssap" },
});
wrapper
.find("input")
.at(2)
.simulate("change", {
target: { name: "confirmPassword", value: "password4321" },
});
await act(async () => {
wrapper.find("form").simulate("submit", fakeEvent);
});
expect(pwFuncs.checkCurrentPassword).toBeCalled();
expect(pwFuncs.comparePW).toBeCalled();
expect(wrapper.find(Alert).length).toEqual(1);
});
测试通过了,所以我的实现没有任何问题,但是... ... act()
函数给我带来了一些麻烦。
下面是错误的原因。
console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:131
Warning: It looks like you're using the wrong act() around your test interactions.
Be sure to use the matching version of act() corresponding to your renderer:
// for react-dom:
import {act} from 'react-dom/test-utils';
// ...
act(() => ...);
// for react-test-renderer:
import TestRenderer from 'react-test-renderer';
const {act} = TestRenderer;
// ...
act(() => ...);
in ConnectFunction (at ChangePassword.js:191)
in form (at ChangePassword.js:131)
in div (at ChangePassword.js:130)
in section (at ChangePassword.js:125)
in main (at ChangePassword.js:124)
in ChangePassword (created by Context.Consumer)
in withRouter(ChangePassword) (created by ConnectFunction)
in ConnectFunction (at ChangePassword.test.js:51)
in Router (created by MemoryRouter)
in MemoryRouter (at ChangePassword.test.js:50)
in Provider (at ChangePassword.test.js:49)
首先,Enzyme的文档说我不应该把我的状态更新函数包在 act()
因为 mount
函数会自动做到这一点(我使用的是React v16.12.0),但如果没有它,测试套件就会失败,说是 act()
是需要的。
从 https:/github.comenzymejsenzyme#reacttestutilsact-wrap。
如果你使用的是React 16.8+和.mount(),Enzyme会用ReactTestUtils.act()来封装apis,包括.simulate()、.setProps()、.setContext()、.invoke(),所以你不需要手动封装。
其次,我已经尝试使用:
import TestRenderer from 'react-test-rendrer';
const { app } = TestRenderer;
但它给出了完全相同的错误。
我不明白为什么会出现这个错误,因为反正所有的测试都通过了。在网上很难找到任何关于使用 act()
所以,如果有人能在这方面提供任何帮助,那就太好了。
好吧,问题中应该有更多的信息。我试图测试的组件被封装在了 withRouter
所以,当我添加了WrappedComponent... ...
const wrapper = mount(
<Provider store={reduxStore}>
<Router>
<ChangePassword.WrappedComponent {...props} />
</Router>
</Provider>
);
...错误就消失了,现在所有测试都正常通过了。希望能帮到大家