我有一个简单的Todo组件,它利用了react redux钩子,我正在使用Ezyme测试它,但是我得到了一个错误或者一个带有浅渲染的空对象,如下所述.

使用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>,在wrapper上调用dive()将返回与v1相同的错误.

提前感谢您的帮助!

推荐答案

我可以测试一个使用redux钩子的组件,该组件使用Enzyme 安装工具,并向Provider 提供模拟存储:

Component

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;

Test

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)
  })
})

Reactjs相关问答推荐

从`redux—thunk`导入thunk `在stackblitz中不起作用

构建next.js项目时状态不变,但在dev服务器中

页面永远加载API/从数据库获取数据

Mantine DatePickerInput呈现错误

shadcn输入+窗体+Zod;一个部件正在改变要被控制的不受控制的输入;

React 错误: 只能用作 元素的子元素,从不直接渲染.请将您的 包裹在

无法使用 Suspense 和 Await 获取数据

如何在不同的路由中渲染相同的页面组件(包括 getServerSideProps)

获取 不能显示为 的后代.错误,但不太确定如何构建我的代码以避免此警告

为什么 useEffect 的初始化对于加载 localStorage 不起作用?

REACT: UseState 没有更新变量(ant design 模态形式)

ReactJS on AWS Amplify与EC2上的Spring boot服务之间的混合内容错误

为什么我会收到此错误:无法在我的react 包上读取 null 的属性(读取useState)?

React - 拖放 UML

MUI - ButtonGroup fullWidth 条件屏幕大小不起作用?

动态添加或删除文本输入字段并将值设置为 React JS 中主要状态的数组

为什么此代码中的 useState 不更新(文本更新但 id 不更新)?

Storybook - 无法解析generated-stories-entry.cjs/字段browser不包含有效的别名配置

理解 React 中的 PrevState

将 dict 值转换并插入到react 钩子的列表中