TheoG
TheoG

Reputation: 1558

Jest/Enzyme: Error: Uncaught [TypeError: Cannot read property 'query' of undefined] on component wrapped in withRouter

So, I have a component that is wrapped in withRouter to access this.props.router.query and is generating the following error:

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

How do I resolve this? My component is as follows:

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

And my Order.test.js component is as follows:

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

Upvotes: 2

Views: 4852

Answers (1)

Agney
Agney

Reputation: 19194

On unit tests, the router package or the withRouter does not have any meaning since we are testing just the component.

To fix this instead of exporting the wrapped component, you can export the individual component too:

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

and use this instance for unit testing.

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

Upvotes: 4

Related Questions