我有一个简单的Todo组件,该组件利用了我正在使用酶进行测试的react-redux钩子,但是出现如下所示的错误或浅渲染的空对象。
使用react-redux的钩子测试组件的正确方法是什么?
Todos.js
const Todos = () => { const { todos } = useSelector(state => state); return ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ); };
Todos.test.js v1
... it('renders without crashing', () => { const wrapper = shallow(<Todos />); expect(wrapper).toMatchSnapshot(); }); it('should render a ul', () => { const wrapper = shallow(<Todos />); expect(wrapper.find('ul').length).toBe(1); });
v1错误:
... Invariant Violation: could not find react-redux context value; please ensure the component is wrapped in a <Provider> ...
Todos.test.js v2
... // imported Provider from react-redux it('renders without crashing', () => { const wrapper = shallow( <Provider store={store}> <Todos /> </Provider>, ); expect(wrapper).toMatchSnapshot(); }); it('should render a ul', () => { const wrapper = shallow(<Provider store={store}><Todos /></Provider>); expect(wrapper.find('ul').length).toBe(1); });
V2测试也失败,因为wrapper是<Provider>和调用dive()上wrapper会返回相同的错误为V1。
wrapper
<Provider>
dive()
在此先感谢您的帮助!
我可以使用酶安装工具测试使用redux钩子的组件,并为提供程序提供模拟存储:
零件
import React from 'react'; import AppRouter from './Router' import { useDispatch, useSelector } from 'react-redux' import StartupActions from './Redux/Startup' import Startup from './Components/Startup' import './App.css'; // This is the main component, it includes the router which manages // routing to different views. // This is also the right place to declare components which should be // displayed everywhere, i.e. sockets, services,... function App () { const dispatch = useDispatch() const startupComplete = useSelector(state => state.startup.complete) if (!startupComplete) { setTimeout(() => dispatch(StartupActions.startup()), 1000) } return ( <div className="app"> {startupComplete ? <AppRouter /> : <Startup />} </div> ); } export default App;
测试
import React from 'react'; import {Provider} from 'react-redux' import { mount, shallow } from 'enzyme' import configureMockStore from 'redux-mock-store' import thunk from 'redux-thunk'; import App from '../App'; const mockStore = configureMockStore([thunk]); describe('App', () => { it('should render a startup component if startup is not complete', () => { const store = mockStore({ startup: { complete: false } }); const wrapper = mount( <Provider store={store}> <App /> </Provider> ) expect(wrapper.find('Startup').length).toEqual(1) }) })