尝试测试使用 redux 的组件时,无法读取 属性 of undefined 错误

Error cannot read property of undefined when trying to test a component that uses redux

我有一个基于 class 的仪表板组件

class Dashboard extends Component {
 ...
 render() {
   return sth
 }
}

const mapStateToProps = state => ({
  userId: state.mainState.userId,
  theme: state.mainState.theme,
  companyUsers: state.mainState.companyUsers,
  activities: state.mainState.activities,
  activityTypes: state.mainState.activityTypes,
  projects: state.mainState.projects
});

const mapDispatchToProps = {
  setMainValue: actions.setMainValue
};

export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Dashboard));

现在我正在尝试使用 jest 和 react-testing-library 开始测试组件。 我创建了一个类似于 article 的 renderWithProvider 函数,并尝试使用自定义渲染函数进行测试。唯一的区别是,在官方 redux 网站中,它 returns mapStateToProps 上的整个状态,因为它很短,而我只返回特定变量。

function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
 const store = createStore(rootReducer, initialState, applyMiddleware(thunk));

  function Wrapper({ children }) {
    return <Provider store={store}>{children}</Provider>;
  }

  Wrapper.propTypes = {
    children: PropTypes.node.isRequired
  };

  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}

// re-export everything
export * from '@testing-library/react';

// override render method
export { renderWithProvider };

当我渲染组件和 运行 测试时

import Dashboard from '.';

import { renderWithProvider } from '../testUtils/renderWithProvider'

test('should ', () => {
  renderWithProvider(<Dashboard />, {
    initialState: {
      userId: 106,
      theme: 'light',
      companyUsers: [],
      activities: [],
      activityTypes: [],
      projects: []
    }
  });
});

我得到:

TypeError: Cannot read property 'userId' of undefined

  334 |
  335 | const mapStateToProps = state => ({
  336 |   userId: state.mainState.userId,

欢迎提出任何建议

编辑:我也试过以下方法:

test('should ', () => {
  renderWithProvider(<Dashboard />, {
    initialState: {
      mainState: {
        userId: 106,
        theme: 'light',
        companyUsers: [],
        activities: [],
        activityTypes: [],
        projects: []
      }
    }
  });
});

但不断出现同样的错误

根据 mapStateToProps 中的预期结构,您的 initialValue 是错误的。您传递的这些属性需要是 mainState 属性 的子属性,而不是根状态的顶级属性。

经过大量挖掘,我发现问题最终与 history 库的使用和项目商店中 rootReducer(history) 的使用有关。

const store = createStore(
  rootReducer(history),
  composeEnhancers(applyMiddleware(routerMiddleware(history), thunk))
);

一旦我将 rootReducer 作为函数和 history 作为参数传递给 rootReducer,类似于在 renderWithProvider 中存储初始化 store.getState() 不再是 undedined,因此 mainState 也及其值:

import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
 const store = createStore(rootReducer(history), initialState, 
 applyMiddleware(thunk));
...
}