【问题标题】:Jest: Mock an NPM module method笑话:模拟一个 NPM 模块方法
【发布时间】:2021-12-11 16:18:29
【问题描述】:

我需要测试一个函数,我从一个名为“heartbeats”的 NPM 包中调用另一个函数:

index.ts

export async function checkUp(app: App, heart, beats: number, iterations: number): Promise<void> {
  // const heart = heartbeats.createHeart(1000, 'checkUp');
  heart.createEvent(beats, { countTo: iterations }, async (count, last) => {
    const secondCheck = await secondCheckStatus();
    if (!secondCheck) {
      app.quit();
    }
  });
}

index.test.ts

import * as Heartbeats from 'heartbeats';
import { secondCheckStatus } from './utils';

...

jest.mock('./utils', () => ({
  ...jest.requireActual('./utils'),
  secondCheckStatus: jest.fn(),
}));

const mockSecondCheckStatus = secondCheckStatus as jest.MockedFunction< typeof secondCheckStatus >;

...

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

...

it('should auto kill app after checks', async () => {
  const mockApp = new MockApp() as unknown as jest.Mocked<App>;
  const mockHeart = Heartbeats.heart as unknown as jest.Mock;

  const mockCreateEvent = Heartbeats.heart.createEvent as unknown as jest.MockedFunction<
    typeof Heartbeats.heart.createEvent
  >;
  mockCreateEvent.mockImplementation((beats, iter, cb) => {
    cb(null, null);
  });

  mockSecondCheckStatus.mockResolvedValueOnce(false);
  mockApp.requestSingleInstanceLock.mockReturnValue(true);
  const isRunning = await checkUp(mockApp, mockHeart, 1, 1);
  await main(mockApp);

  expect(mockApp.quit).toHaveBeenCalledTimes(1);
  expect(isRunning).toBe(false);
});

但我总是得到:

TypeError: 无法读取未定义的属性 'mockImplementation'

  83 |     typeof Heartbeats.heart.createEvent
  84 |   >;
> 85 |   mockCreateEvent.mockImplementation((beats, iter, cb) => {

知道我做错了什么吗?

非常感谢(我与 Jest 顺利合作还有很长的路要走)

【问题讨论】:

  • secondCheckStatus 来自哪里?
  • 我已经使用secondCheckStatus 参考编辑了测试文件
  • 我在测试文件中添加了const mockSecondCheckStatus = secondCheckStatus as jest.MockedFunction&lt; typeof secondCheckStatus &gt;;,我忘记了。

标签: typescript unit-testing jestjs mocking


【解决方案1】:

由于checkUp 函数接受appheart 作为其参数,您可以创建与这些参数类型或接口匹配的模拟对象。

import关键字只导入了secondCheckStatus函数,你必须使用jest.mock()方法来模拟它。

要处理模拟对象/函数的 TS 类型问题,您可以使用 ts-jestmocked(item: T, deep = false) 辅助函数。

例如

index.ts:

import { secondCheckStatus } from './utils';

export async function checkUp(app, heart, beats: number, iterations: number): Promise<void> {
  heart.createEvent(beats, { countTo: iterations }, async (count, last) => {
    const secondCheck = await secondCheckStatus();
    if (!secondCheck) {
      app.quit();
    }
  });
}

util.ts:

export async function secondCheckStatus() {
  return true;
}

index.test.ts:

import { checkUp } from './';
import { secondCheckStatus } from './utils';
import { mocked } from 'ts-jest/utils';

jest.mock('./utils', () => ({
  ...(jest.requireActual('./utils') as object),
  secondCheckStatus: jest.fn(),
}));

const mockSecondCheckStatus = mocked(secondCheckStatus);

describe('69720608', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });
  test('should pass', async () => {
    const mockApp = {
      quit: jest.fn(),
    };
    const mockHeart = {
      createEvent: jest.fn().mockImplementation(async (beats, options, callback) => {
        await callback();
      }),
    };
    await checkUp(mockApp, mockHeart, 1, 1);
    expect(mockSecondCheckStatus).toBeCalledTimes(1);
    expect(mockApp.quit).toBeCalledTimes(1);
  });
});

测试结果:

 PASS  examples/69720608/index.test.ts (13.424 s)
  69720608
    ✓ should pass (4 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   88.89 |       50 |      75 |    87.5 |                   
 index.ts |     100 |       50 |     100 |     100 | 6                 
 utils.ts |      50 |      100 |       0 |      50 | 2                 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.478 s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2018-10-10
    • 2019-04-10
    • 2018-12-31
    相关资源
    最近更新 更多