如何使用另一个 class 实例模拟从文件导出的 class 实例

How to mock class instance exported from file with another class instance

我有这个文件

// src/history
import { createBrowserHistory } from 'history'
const history = createBrowserHistory();
export default history;

historyBrowserHistory class 的实例。它在实际代码中使用:

// src/SampleCode.js
import history from '../../history';
export default function SampleCode = () => {
  const onClick = () => history.push(`/login`);
  return (<Button onCLick={onClick}>Click</Button>)
}

我想用另一个 class MemoryHistory 的实例模拟这个 history。像这样:

// src/sample.test.js
it('should redirect to /login', () => {
  const mockHistory = createMemoryHistory();
  const historyPush = jest.spyOn(mockHistory, 'push').mockResolvedValue({});
  jest.mock('./history', () => mockHistory);
  // Click button here
  await waitFor(() => expect(historyPush).toBeCalledWith('/login'));
}

但这种方法不起作用:historyPush 根本没有被调用

使用jest.doMock(moduleName, factory, options)确保在导入component之前模拟./history模块。

例如

sample.jsx:

import React from 'react';
import history from './history';

export default function SampleCode() {
  const onClick = () => history.push(`/login`);
  return <button onClick={onClick}>Click</button>;
}

history.js:

import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;

sample.test.jsx:

import { createMemoryHistory } from 'history';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

describe('68311534', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('should pass', () => {
    const memoryHistory = createMemoryHistory();
    const pushSpy = jest.spyOn(memoryHistory, 'push');
    jest.doMock('./history', () => memoryHistory);
    const { default: Sample } = require('./sample');
    render(<Sample />);
    const button = screen.getByText('Click');
    userEvent.click(button);
    expect(pushSpy).toBeCalledWith('/login');
  });
});

测试结果:

 PASS  examples/68311534/sample.test.jsx (15.495 s)
  68311534
    ✓ should pass (11006 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 sample.jsx |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        17.53 s