测试包含在 withRouter 中的 react 组件(最好使用 jest/enzyme)

IT技术 reactjs unit-testing react-router jestjs enzyme
2021-05-14 12:57:40

我有一个 React 组件,它包含在高阶组件 withRouter 中,如下所示:

module.exports = withRouter(ManageProfilePage);

我的路线如下:

<Route path="/" component={AdrApp}>
    <IndexRoute component={Login}/>
    <Route component={CheckLoginStatus}>
        <Route path="manage-profiles/:profileId" component=
        {ManageProfilesPage}/>
     </Route>
    <Route path="*" component={notFoundPage}/>
</Route>

我需要使用一次 Router 生命周期方法,这就是我需要 withRouter 的原因:

class ManageProfilePage extends React.Component {
    componentDidMount() {
    this.props.router.setRouteLeaveHook(this.props.route, () => {
      ...
    })
    render(){
    ... 
    }
}

我需要使用 Jest/Enzyme 测试这个组件,我编写了如下的测试用例:

describe('manage profile page test suite', () => {


    it('snapshot test', () => {

        const setRouteLeaveHook =jest.fn();

        let wrapper = shallow(
            <ManageProfilePage params={{id : 25, router: 
        setRouteLeaveHook}}/>
        );
      expect(wrapper).toMatchSnapshot();
    })
   }) 

问题是它没有渲染一层深。我正在粘贴下面的快照:

exports[`manage drug term page test suites snapshot test 1`] = `
<ManageProfilePage
  params={
    Object {
      "id": 25,
      "router": [Function],
    }
  }
/>
`;

有没有什么不同的方法可以编写我的测试用例,以便我能够将 ManageProfilePage 呈现至少 1 级深?它无法渲染,因为它包含在 WithRouter 中?我们如何测试这些类型的组件?

4个回答

通常,如果我们尝试测试这样的组件,我们将无法渲染它,因为它被包装在 WithRouter 中(WithRouter 是一个组件的包装器,它提供了路由器props,如匹配、路由和历史记录,以直接在组件中使用)。module.exports = withRouter(ManageProfilePage);

为了渲染这样的组件,我们必须明确地告诉它使用 WrappedComponent 关键字来渲染被包装的组件。例如。我们将使用以下代码进行快照测试:

describe('manage profile page test suite', () => {


    it('snapshot test', () => {

        const setRouteLeaveHook =jest.fn();

        let wrapper = shallow(
            <ManageProfilePage.WrappedComponent params={{id : 25, router: 
        setRouteLeaveHook}}/>
        );
      expect(wrapper).toMatchSnapshot();
    })
   }) 

这将告诉酶对包裹在 WithRouter 中的组件 ManageProfilePage 进行浅渲染(浅渲染仅渲染该特定组件并跳过子组件)。

浅渲染只会渲染一个级别,这是它的规范的一部分。

你可以使用 Mount 来渲染整棵树,但我认为你不能限制它渲染的深度。

在任何情况下,当使用高阶组件时,我通常也只导出基本组件(在包装它之前),这样我就可以在没有包装器的情况下进行所有测试,并且只需为所需的提供者传递模拟。

Connect带有 redux组件相同的事情,您导出常规组件并在其上测试不同的props,而不是连接的props。

还要注意,有些with...包装器不公开内部实例(有些可以,有些不公开),因此测试您自己的组件而不是包装器也有帮助。

我想你应该试试这个

    describe('manage profile page test suite', () => {


    it('snapshot test', () => {
        let wrapper = shallow(
            <ManageProfilePage.WrappedComponent/>
        );
      expect(wrapper).toMatchSnapshot();
    })
   }) 

我做了什么解决了这个问题:

在“this.props.match.params.id”中使用了post组件

在测试用例中

const miniProps = {
    其他props,
    匹配:{参数:{id:'112'}}
};

const 包装器 = 浅();