如何用玩笑模拟从方法内部启动的构造函数

时间:2020-10-27 06:09:15

标签: javascript ecmascript-6 jestjs mocking

我有一个定义2个类的脚本,并且1个在另一个的构造函数中实例化。我如何模拟嵌套构造函数,以便可以测试父构造函数?

export default class Foo {
  // i want to test this constructor...
  constructor() {
    new Bar
  }
}

export class Bar {
  // but mock this constructor
  constructor() {}
}

另外,我试图监视Bar构造函数,以断言它已被调用

我尝试了几种不同的方法,但是未能获得我想要的结果。我是开玩笑的嘲笑库的新手

1 个答案:

答案 0 :(得分:2)

需要对模块导出语句进行一些修改。然后,我们可以使用jest.spyOn(object, methodName)方法来模拟Bar类的实现。编译后看看code。我们在模块导出对象中创建模拟的Bar,并在Foo类中使用它。它与被嘲笑的对象具有相同的引用。

推荐方式:

  1. 依赖注入
  2. 每个文件仅包含一个类。这样我们就可以使用jest.mockjest.doMock方法来模拟类,而无需修改模块导出语句。

例如

index.ts

export default class Foo {
  constructor() {
    new exports.Bar();
  }
}

class Bar {
  constructor() {
    console.log('real Bar constructor implmentation');
  }
}

exports.Bar = Bar;

index.test.ts

import * as mod from './';

console.log(mod);

describe('64549093', () => {
  it('should pass', () => {
    const BarConstructorMock = jest.spyOn(mod as any, 'Bar').mockImplementationOnce(() => {
      console.log('fake Bar constructor implmentation');
    });
    new mod.default();
    expect(BarConstructorMock).toBeCalled();
  });
});

单元测试结果:

 PASS  src/stackoverflow/64549093/index.test.ts (9.905s)
  64549093
    ✓ should pass (5ms)

  console.log src/stackoverflow/64549093/index.test.ts:3
    { default: [Function: Foo], Bar: [Function: Bar] }

  console.log src/stackoverflow/64549093/index.test.ts:8
    fake Bar constructor implmentation

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.751s, estimated 12s

关于jestjsTypeScript的配置,请参见示例: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/64549093