酶和react-router:如何使用 useHistory 浅渲染组件

IT技术 reactjs react-router react-hooks enzyme
2021-05-23 01:15:32

我一直在尝试使用 来呈现组件shallow,该组件enzyme.

该组件正在使用useHistoryfrom react-router-dom

const baseMatch: match<{ id: string }> = { /* path, url, params */};
const location = createLocation(baseMatch.url);

describe('MyComponent', () => {
  const baseProps = {
    history: createMemoryHistory(),
    location: createLocation(baseMatch.url),
    match: baseMatch
  };

  beforeEach(() => {
    jest.mock('react-router-dom', () => ({
      useHistory: jest.fn()
    }));
  });

  afterEach(() => { jest.clearAllMocks() });

  it('renders blah blah', () => {
    const wrapper = shallow(<MyComponent {...baseProps} />);
    // testing MyComponent here...
  });

我参考了这篇文章,并jest.mock以同样的方式放置

然而,这导致TypeError: Cannot read property 'history' of undefined.

控制台说:

MyComponent › renders blah blah

    TypeError: Cannot read property 'history' of undefined

      24 | const MyComponent = (props: IProps) => {
      25 |   console.log('useHistory', useHistory);
    > 26 |   let history = useHistory();

奇怪的是,console.log上面的第 25 行打印了useHistory(换句话说,它不是未定义的) 的实现。

显然,useHistory没有被嘲笑。我怀疑这useHistory不能被嘲笑shallow(在上面的帖子中,海报使用的是mount())。

不过,我不是100%肯定,因为我无法找到,如果shallow是兼容useHistory的的文档或不enzymereact-router

是否有可能使用shallowuseHistory任何建议将被认真考虑。

1个回答

文档

注意:为了正确模拟,Jest 需要 jest.mock('moduleName') 与 require/import 语句在同一范围内。

因此,不要嘲笑 react-router-dom beforeEach- 尝试将其置于顶级范围:

jest.mock('react-router-dom', () => ({
  useHistory: jest.fn()
}));

const baseMatch: match<{ id: string }> = { /* path, url, params */};
const location = createLocation(baseMatch.url);


describe('MyComponent', () => {
  const baseProps = {
    history: createMemoryHistory(),
    location: createLocation(baseMatch.url),
    match: baseMatch
  };

...