首页 > 解决方案 > Jest unit-testing if super() is called

问题描述

I have a custom error class that extends the built-in Error class in Javascript. The problem I came up with is that "super()" method is not checked if it is called or not through my Jest unit testing.

export class AppError extends Error {
  public name: string;
  public message: string;
  public status?: number;
  public data?: any;
  constructor(message: string, status?: number, data?: any) {
    super(); <-- this guy!!
    this.name = 'AppError';
    this.status = status || 500;
    this.message = message;
    this.data = data;
  }
}

Is there any way to test it? Thanks.

标签: unit-testingecmascript-6jestjssuper

解决方案


没有理由检查是否super()在原生 ES6 类和使用 Babel 转译的类中都没有调用。

不调用super子类构造函数将导致类实例化错误:

ReferenceError:在访问“this”或从派生构造函数返回之前,必须在派生类中调用超级构造函数

Babel也为此提供了保障

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

可以super()通过模拟子类原型来检查是否调用了父构造函数(对断言参数很有用),例如:

let ParentOriginal;
let ParentMock;

beforeEach(() => {
  ParentOriginal = Object.getPrototypeOf(AppError);
  ParentMock = jest.fn();
  Object.setPrototypeOf(AppError, ParentMock);
});

it('..', () => {
  new AppError(...);
  expect(ParentMock.mock.calls.length).toBe(1);
})

afterEach(() => {
  Object.setPrototypeOf(AppError, ParentOriginal);
});

预计它将super在本地类和使用 Babel 转译的类中进行模拟。

但是这个测试是多余的,因为丢失super()无论如何都会导致错误。AppError继承自的测试Error是这里需要测试的所有内容:

expect(new AppError(...)).toBeInstanceOf(Error)

推荐阅读