为什么我的 React 应用程序 Jest/Enzyme setState 测试失败了?
Why is this Jest/Enzyme setState test failing for my React app?
预计:
测试运行并在登录组件中更新状态,然后启用通知组件(错误消息)被发现
结果:
测试失败,预期 1,收到 0
最初在我添加 redux 和 store 之前,因此需要在我的测试中使用 store 和 provider 逻辑,这个 Jest/Enzyme 测试通过了。
Login.test(更新当前版本)
import React from 'react'
import { Provider } from "react-redux"
import ReactTestUtils from 'react-dom/test-utils'
import { createCommonStore } from "../../store";
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
// import Login from './Login'
import { LoginContainer } from './Login';
import Notification from '../common/Notification'
const store = createCommonStore();
const user = {
id: 1,
role: 'Admin',
username: 'leongaban'
};
const loginComponent = mount(
<Provider store={store}>
<LoginContainer/>
</Provider>
);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
Login.test(之前通过的版本,但没有 Redux 存储逻辑)
import React from 'react'
import ReactTestUtils from 'react-dom/test-utils'
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
import Login from './Login'
import Notification from '../common/Notification'
const loginComponent = shallow(<Login />);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
你的问题是,通过将 redux 存储逻辑混合到测试中,loginComponent
变量不再表示 Login
的实例,而是 Provider
包装和实例的实例共 Login.
因此当你这样做时
loginComponent.setState({ error: true })
您实际上是在 Provider
实例上调用 setState
。
我建议测试用 connect
包装的 LoginComponent
以与存储状态分开生成 LoginContainer
。 Redux GitHub 存储库有 a great article on testing connected components,它给出了如何执行此操作的大纲。
总结一下你需要做什么
- 分别导出
LoginComponent
和 LoginContainer
- 从容器中单独测试
LoginComponent
,基本上是在混合 redux store state 之前做你之前的工作测试。
- 为
LoginContainer
编写单独的测试,在其中测试 mapStateToProps
、mapDispatchToProps
和 mergeProps
功能。
希望这对您有所帮助!
预计:
测试运行并在登录组件中更新状态,然后启用通知组件(错误消息)被发现
结果:
测试失败,预期 1,收到 0
最初在我添加 redux 和 store 之前,因此需要在我的测试中使用 store 和 provider 逻辑,这个 Jest/Enzyme 测试通过了。
Login.test(更新当前版本)
import React from 'react'
import { Provider } from "react-redux"
import ReactTestUtils from 'react-dom/test-utils'
import { createCommonStore } from "../../store";
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
// import Login from './Login'
import { LoginContainer } from './Login';
import Notification from '../common/Notification'
const store = createCommonStore();
const user = {
id: 1,
role: 'Admin',
username: 'leongaban'
};
const loginComponent = mount(
<Provider store={store}>
<LoginContainer/>
</Provider>
);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
Login.test(之前通过的版本,但没有 Redux 存储逻辑)
import React from 'react'
import ReactTestUtils from 'react-dom/test-utils'
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
import Login from './Login'
import Notification from '../common/Notification'
const loginComponent = shallow(<Login />);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
你的问题是,通过将 redux 存储逻辑混合到测试中,loginComponent
变量不再表示 Login
的实例,而是 Provider
包装和实例的实例共 Login.
因此当你这样做时
loginComponent.setState({ error: true })
您实际上是在 Provider
实例上调用 setState
。
我建议测试用 connect
包装的 LoginComponent
以与存储状态分开生成 LoginContainer
。 Redux GitHub 存储库有 a great article on testing connected components,它给出了如何执行此操作的大纲。
总结一下你需要做什么
- 分别导出
LoginComponent
和LoginContainer
- 从容器中单独测试
LoginComponent
,基本上是在混合 redux store state 之前做你之前的工作测试。 - 为
LoginContainer
编写单独的测试,在其中测试mapStateToProps
、mapDispatchToProps
和mergeProps
功能。
希望这对您有所帮助!