首页 > 解决方案 > Jest/Enzyme:错误:未捕获 [TypeError: Cannot read property 'query' of undefined] 在 withRouter 包裹的组件上

问题描述

所以,我有一个组件被包裹在里面withRouter访问this.props.router.query并产生以下错误:

console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29 Error: Uncaught [TypeError: Cannot read property 'query' of undefined]

我该如何解决这个问题?我的组件如下:

import { withRouter } from 'next/router';

class Order extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    const { onToken } = this.props.router.query;

    return (
      .......
    );
  }
}

export default withRouter(Order);

我的Order.test.js组件如下:

import Order, { SINGLE_ORDER_QUERY } from '../components/Order';
import { fakeOrder } from '../lib/testUtils';

const mocks = [
  {
    request: { query: SINGLE_ORDER_QUERY, variables: { id: 'ord123' } },
    result: { data: { order: fakeOrder() } },
  },
];

describe('<Order/>', () => {
  it('renders the order', async () => {
    const wrapper = mount(
      <MockedProvider mocks={mocks}>
        <Order id="ord123" />
      </MockedProvider>
    );
    await wait();
    wrapper.update();
    const order = wrapper.find('div[data-test="order"]');
    expect(toJSON(order)).toMatchSnapshot();
  });
});

标签: reactjsunit-testingjestjsenzyme

解决方案


在单元测试中,router 包或withRouter没有任何意义,因为我们只是在测试组件。

要解决此问题而不是导出包装的组件,您也可以导出单个组件:

import { withRouter } from 'next/router';

export class Order extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    const { onToken } = this.props.router.query;

    return (
      .......
    );
  }
}

export default withRouter(Order);

并将此实例用于单元测试。

import { Order, SINGLE_ORDER_QUERY } from '../components/Order';
import { fakeOrder } from '../lib/testUtils';

const mocks = [
  {
    request: { query: SINGLE_ORDER_QUERY, variables: { id: 'ord123' } },
    result: { data: { order: fakeOrder() } },
  },
];

describe('<Order/>', () => {
  it('renders the order', async () => {
    const router = {
      query: {
        onToken: 1 // Whatever value you want to provide it
      }
    }
    const wrapper = mount(
      <MockedProvider mocks={mocks}>
        <Order id="ord123" router={router} />
      </MockedProvider>
    );
    await wait();
    wrapper.update();
    const order = wrapper.find('div[data-test="order"]');
    expect(toJSON(order)).toMatchSnapshot();
  });
});

推荐阅读