在Jest中模拟全局函数

时间:2019-12-12 19:07:40

标签: angular unit-testing mocking jestjs

我正在用Jest测试某些功能,并且具有以下功能:

functions.ts

export function processEvent = () => {
    return (event: IEventData) => {
        ...
        const eventType = getEventType(event);
        ...
    }
}

export function getEventType(event: IEventData): string {
    ...
}

functions.test.ts

import * as Functions from './functions.ts';

describe('processEvent', () => {
    let processor: (event: IEventData) => {};
    let getEventTypeSpy: jest.SpyInstance;
    let event: IEventData;

    beforeEach(() => {
        processor = Functions.processEvent();
        getEventTypeSpy = jest.spyOn(Functions, 'getEventType');
        event = <IEventData>{};
    });

    it('should ...', () => {
        getEventTypeSpy.mockreturnValueOnce(...);
        ...
    });
}

functions.ts没有指定名称空间,因此它位于全局位置。当我逐步浏览spec.ts文件时,getEventTypeSpy的创建是正确的,但是一旦它从测试中进入functions.ts,该函数就会删除模拟字段并仅调用其实际值。实施。我知道在functions.ts中的所有函数周围添加名称空间将解决此问题,但这不是一种选择。如何模拟getEventType()

1 个答案:

答案 0 :(得分:0)

原因是export关键字属于ES6,在babel编译并将其转换为es5之后,函数(getEventType)的名称将被更改。这就是jest.spyOn失败的原因。这是单元测试解决方案:

functions.ts

export interface IEventData {}

export function processEvent() {
  return (event: IEventData) => {
    const eventType = exports.getEventType(event);
    return eventType;
  };
}

function getEventType(event: IEventData): string {
  return '';
}

exports.getEventType = getEventType;

functions.test.ts

import * as Functions from './functions';
import { IEventData } from './functions';

describe('processEvent', () => {
  let processor: (event: IEventData) => {};
  let getEventTypeSpy: jest.SpyInstance;
  let event: IEventData;

  beforeEach(() => {
    processor = Functions.processEvent();
    getEventTypeSpy = jest.spyOn(Functions as any, 'getEventType');
    event = {} as IEventData;
  });
  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('should pass', () => {
    getEventTypeSpy.mockReturnValueOnce('message');
    const actual = processor(event);
    expect(actual).toBe('message');
    expect(getEventTypeSpy).toBeCalledWith(event);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59311270/functions.test.ts (12.949s)
  processEvent
    ✓ should pass (8ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |    83.33 |      100 |    66.67 |    83.33 |                   |
 functions.ts |    83.33 |      100 |    66.67 |    83.33 |                11 |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.997s, estimated 17s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59311270