我有一个简单的Todo组件,该组件利用了我正在使用酶进行测试的react-redux钩子,但是出现如下所示的错误或浅渲染的空对象。
使用react-redux的钩子测试组件的正确方法是什么?
Todos.js
const Todos = () => {
const { todos } = useSelector(state => state);
return (
{todos.map(todo => (
- {todo.title}
))}
);
};
Todos.test.js v1
...
it('renders without crashing', () => {
const wrapper = shallow( );
expect(wrapper).toMatchSnapshot();
});
it('should render a ul', () => {
const wrapper = shallow( );
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...
Todos.test.js v2
... Invariant Violation: could not find react-redux context value; please ensure the component is wrapped in a...
V2测试也失败,因为wrapper
是
和调用dive()
上wrapper
会返回相同的错误为V1。
在此先感谢您的帮助!
我可以使用酶安装工具测试使用redux钩子的组件,并向Provider提供模拟存储:
零件
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 ({startupComplete ?); } 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() expect(wrapper.find('Startup').length).toEqual(1) }) })
如果您使用另一个文件中定义的函数选择器,则@abidibo之外还有另一种方法。您可以模拟useSelector
和选择器功能,然后shallow
从酶中使用:
零件
import * as React from 'react'; import { useSelector } from 'react-redux'; import Spinner from './Spinner'; import Button from './Button '; import { getIsSpinnerDisplayed } from './selectors'; const Example = () => { const isSpinnerDisplayed = useSelector(getIsSpinnerDisplayed); return isSpinnerDisplayed ?: ; }; export default Example;
选择器
export const getIsSpinnerDisplayed = state => state.isSpinnerDisplayed;
测试
import * as React from 'react'; import { shallow } from 'enzyme'; import Example from './Example'; import Button from './Button '; import { getIsSpinnerDisplayed } from './selectors'; jest.mock('react-redux', () => ({ useSelector: jest.fn(fn => fn()), })); jest.mock('./selectors'); describe('Example', () => { it('should render Button if getIsSpinnerDisplayed returns false', () => { getIsSpinnerDisplayed.mockReturnValue(false); const wrapper = shallow(); expect(wrapper.find(Button).exists()).toBe(true); }); });
可能有点hacky,但对我来说效果很好:)