简体   繁体   中英

Mocking global functions in Jest

I'm testing some functions with Jest and have the following:

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 has no namespace specified, so it's just sitting in global. When I step through the spec.ts file, the getEventTypeSpy was created properly, but as soon as it steps into functions.ts from the test, the function has the mock fields removed and just calls its actual implementation. I know that throwing a namespace around all the functions in functions.ts will resolve the issue, but that is not an option. How do I mock getEventType() ?

The reason is, export keyword belongs to ES6, after babel compile and transform them to es5, the function( getEventType ) name will be changed. That's why jest.spyOn failed. Here is the unit test solution:

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);
  });
});

Unit test result with coverage report:

 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

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59311270

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM