TypeError:无法读取未定义(笑话)的属性“ location”

时间:2020-02-14 21:43:17

标签: reactjs unit-testing react-router jestjs enzyme

我有一个简单的组件,该组件使用React Router中的useLocation钩子。

// App.jsx

import React from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  const location = useLocation();
  const pathName = location.pathname;
  useEffect(() => {
    // Use pathName here
  }, [pathName]);
}

// App.test.js

import App from './App';

describe('App component', () => {
  it('Renders correctly', () => {
    const wrapper = shallow(<App />);

    expect(wrapper).toMatchSnapshot();
  });
});

//更新App.test.js(带有笑话模拟)

import App from './App';

describe('App component', () => {
  jest.mock('react-router-dom', () => ({
    useLocation: jest.fn().mockReturnValue({
      pathname: '/another-route',
      search: '',
      hash: '',
      state: null,
      key: '5nvxpbdafa',
    }),
  }));

  it('Renders correctly', () => {
    const wrapper = shallow(<App />);

    expect(wrapper).toMatchSnapshot();
  });
});

能否请您告诉我该如何解决?谢谢。

3 个答案:

答案 0 :(得分:8)

只需将您的jest.mock声明移到文件顶部,它应该可以工作:

import App from './App';

jest.mock('react-router-dom', () => ({
    useLocation: jest.fn().mockReturnValue({
      pathname: '/another-route',
      search: '',
      hash: '',
      state: null,
      key: '5nvxpbdafa',
    }),
}));

describe('App component', () => {
  it('Renders correctly', () => {
    const wrapper = shallow(<App />);

    expect(wrapper).toMatchSnapshot();
  });
});

答案 1 :(得分:2)

问题是您需要指定正在使用es6模块语法。试试这个:

import App from './App';



jest.mock('react-router-dom', () => ({
    __esModule: true,
    useLocation: jest.fn().mockReturnValue({
      pathname: '/another-route',
      search: '',
      hash: '',
      state: null,
      key: '5nvxpbdafa',
    }),
  }));

describe('App component', () => {
  it('Renders correctly', () => {
    const wrapper = shallow(<App />);

    expect(wrapper).toMatchSnapshot();
  });
});

Reference.

答案 2 :(得分:2)

以防万一,其他人也面临类似的问题。

我的方法有两个问题。首先,我使用了模拟里面的describe(感谢Johnny和MGarcia帮助我弄清楚了)。

但是,我在移动模拟代码后又遇到了另一个错误。错误:React.createElement: type is invalid — expected a string

那是我的另一个Jest新手错误,忘记了全部是JavaScript。通过这种方法,模拟useLocation的副作用是使react-router-dom中的其余方法不可用。

这是对我有用的方法:

https://github.com/facebook/jest/issues/936#issuecomment-265074320

最终解决方案:

function mockFunction() {
  const original = require.requireActual('react-router-dom');
  return {
    ...original,
    useLocation: jest.fn().mockReturnValue({
      pathname: '/another-route',
      search: '',
      hash: '',
      state: null,
      key: '5nvxpbdafa',
    }),
  };
}

jest.mock('react-router-dom', () => mockFunction());