如果调用 super() 则开玩笑地进行单元测试

Jest unit-testing if super() is called

我有一个自定义错误 class,它扩展了 Javascript 中的内置错误 class。我遇到的问题是 "super()" 方法未通过我的 Jest 单元测试检查是否被调用。

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

有什么方法可以测试吗?谢谢

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

不在子 class 构造函数中调用 super 将导致 class 实例化时出错:

ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

Babel provides a safeguard 同样:

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

可以通过模拟子 class 原型来检查父构造函数是否被调用(可能对断言 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);
});

预计会在原生 classes 和使用 Babel 转译的 classes 中模拟 super

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

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