【问题标题】:Error cannot read property of undefined when trying to test a component that uses redux尝试测试使用 redux 的组件时出现错误无法读取未定义的属性
【发布时间】:2021-04-07 10:40:23
【问题描述】:

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

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 网站中,它返回 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:无法读取未定义的属性“userId”

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

欢迎提出建议

编辑:我还尝试了以下方法:

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

但总是遇到同样的错误

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

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

    【讨论】:

    • 那应该怎么通过呢?我也尝试过通过initialState: {mainState: ... } },但不断收到同样的错误。你能举个例子吗?
    • 嗯 initialState: {mainState: { userId: 106, ... } } 应该是正确的。我可以稍后再看这个——我在用手机。
    • 好的。谢谢你。我会等待。值得一提的是,这个组件是作为路由的结果显示的,我还没有将它包含在我的自定义渲染函数中。这时候会不会有问题?
    • 我不这么认为,因为错误肯定是在 mapStateToProps 中未定义 state.mainState。
    • 我的想法完全一样,但想确认一下。
    【解决方案2】:

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

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

    一旦我将 rootReducer 作为函数和历史作为参数传递给 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));
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2021-01-29
      • 2023-03-23
      • 2019-04-06
      • 1970-01-01
      • 2021-03-31
      • 2022-11-02
      相关资源
      最近更新 更多