如何在像 jest.mock 这样的 mocha 生态系统中模拟整个类/模块级的依赖关系?

问题描述

我正在尝试对一个看起来像这样的模块进行单元测试

import { Countdown } from "./database/orm";

export class PersistentTimer {
    protected constructor(...) { ... }
    
    // This object requires writing to a database,so I protect the constructor and
    // force construction through an async interface
    public static async create(...) {
        const entity = new Countdown();
        // do stuff
        await entity.save();
        return new PersistentTimer(entity);
    }
}

我正在 mocha 生态系统中寻找类似 jest.mock 的东西来模拟 Countdown 模块,因为它有副作用,以便我可以对这个模块进行单元测试。 Sinon 似乎只处理传递给函数调用函数、对象的属性或对象实例。

解决方法

您可以使用 link seams 存根 ./database/orm 模块。

这是 CommonJS 版本,因此我们将使用 proxyquire 来构建接缝。

例如

main.ts

import { Countdown } from './database/orm';

export class PersistentTimer {
  protected constructor(entity: Countdown) {}

  public static async create() {
    const entity = new Countdown();
    await entity.save();
    return new PersistentTimer(entity);
  }
}

main.test.ts

import sinon from 'sinon';
import proxyquire from 'proxyquire';
import { expect } from 'chai';

describe('65399764',() => {
  it('should pass',async () => {
    const countdownInstanceStub = {
      save: sinon.stub(),};
    const CountdownStub = sinon.stub().returns(countdownInstanceStub);
    const { PersistentTimer } = proxyquire('./main.ts',{
      './database/orm': {
        Countdown: CountdownStub,},});
    const persistentTimer = await PersistentTimer.create();
    sinon.assert.calledOnce(CountdownStub);
    sinon.assert.calledOnce(countdownInstanceStub.save);
    expect(persistentTimer).to.be.instanceOf(PersistentTimer);
  });
});

单元测试结果:

  65399764
    ✓ should pass (1848ms)


  1 passing (2s)

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   85.71 |      100 |   66.67 |   85.71 |                   
 65399764          |     100 |      100 |     100 |     100 |                   
  main.ts          |     100 |      100 |     100 |     100 |                   
 65399764/database |      50 |      100 |       0 |      50 |                   
  orm.ts           |      50 |      100 |       0 |      50 | 3                 
-------------------|---------|----------|---------|---------|-------------------