Создание mockImplementation для es6 Class 'Stati c Метод в Jest - PullRequest
0 голосов
/ 20 марта 2020

Я тестирую функцию, которая внутри нее вызывает метод stati c из контроллера (класса es6), который возвращает результат выборки API. Поскольку я пишу модульное тестирование, а контроллер имеет свои собственные тесты, я хочу смоделировать (технически подделать) метод stati c из класса, чтобы дать мне разные типы ответов.

// Controller.js
class Controller {
  static async fetchResults() {} // the method I want to fake
}
// func.js - the function I am writing the test for
const func = async (ctx) => {
  const data = await Controller.fetchResults(ctx.req.url)

  if (containsErrors(data)) ... // do some logic

  return { ...data, ...otherStuff }
}

Эта попытка подделать static async fetchResults() ничего не делает, и тест пытается вызвать метод fetchResults исходного контроллера.

// func.test.js
describe('when data is successfuly fetched', () => {
  jest.mock('./Controller.js', () => jest.fn().mockImplementation(() => ({
    fetchResults: jest.fn(() => mockResponse),
  });

  it('returns correct information', async () => {
    expect(await func(context)).toEqual({ ...mockResponse, ...otherStuff });
  });
});

Эта следующая попытка выглядит как макет работает в некоторой степени, но возвращаемое значение равно undefined, а не { ...mockResponse, ...otherStuff }, что говорит о том, что весь класс вытаскивается, но fetchResults не найден из-за того, что он является static методом, а не метод экземпляра.

import Controller from './Controller.js'

describe('when data is successfuly fetched', () => {
  Controller.mockImplementation(jest.fn(() => ({
    fetchHotel: () => { ...mockResponse, ...otherStuff }
  })

  it('returns correct information', async () => {
    expect(await func(context)).toEqual({ ...mockResponse, ...otherStuff });
  });
});

1 Ответ

1 голос
/ 23 марта 2020

Для этого можно использовать jest.spyOn (object, methodName) .

Например

controller.js:

export class Controller {
  static async fetchResults(url) {
    return { result: 'real result' };
  }
}

func.js:

import { Controller } from './controller';

const func = async (ctx) => {
  const data = await Controller.fetchResults(ctx.req.url);
  // do some logic
  return { ...data };
};

export { func };

func.test.js:

import { Controller } from './controller';
import { func } from './func';

describe('60776211', () => {
  it('should pass', async () => {
    const fetchResultsSpy = jest.spyOn(Controller, 'fetchResults').mockResolvedValueOnce({ result: 'fake data' });
    const ctx = { req: { url: 'example.com' } };
    const actual = await func(ctx);
    expect(actual).toEqual({ result: 'fake data' });
    fetchResultsSpy.mockRestore();
  });
});

Результаты модульных испытаний с отчетом о покрытии:

 PASS  stackoverflow/60776211/func.test.ts
  60776211
    ✓ should pass (5ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |   91.67 |      100 |      75 |   88.89 |                   
 controller.ts |      80 |      100 |      50 |      75 | 3                 
 func.ts       |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.922s, estimated 11s
...