简体   繁体   English

在 Jest 中为 es6 类的静态方法创建模拟实现

[英]Create mockImplementation for es6 Class' Static Method in Jest

I am testing a function which, inside it, calls a static method from a (es6 class) controller which returns the result of an API fetch.我正在测试一个函数,该函数在其中调用来自(es6 类)控制器的静态方法,该方法返回 API 获取的结果。 Since I'm writing a unit test and the controller has its own tests, I want to mock (technically fake) the static method from the class to give me different types of responses.由于我正在编写单元测试并且控制器有自己的测试,因此我想模拟(技术上伪造)类中的静态方法,以便为我提供不同类型的响应。

// 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 }
}

This attempt to fake the static async fetchResults() does nothing and the test attempts to call the original controller's fetchResults method.这种伪造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 });
  });
});

This next attempt appears like the mock is working to some degree, but the returned value is undefined rather than { ...mockResponse, ...otherStuff } which suggests that the entire class is being mocked out but fetchResults isn't found due to it being a static method rather than an instance method.下一次尝试似乎模拟在某种程度上起作用了,但返回的值是undefined而不是{ ...mockResponse, ...otherStuff }这表明整个类都被fetchResults了,但由于找不到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 });
  });
});

You can use jest.spyOn(object, methodName) to do this.您可以使用jest.spyOn(object, methodName)来做到这一点。

Eg例如

controller.js : controller.js

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

func.js : 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 : 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();
  });
});

unit test results with coverage report:带有覆盖率报告的单元测试结果:

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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