Kevin Lu
Kevin Lu

Reputation: 373

How to mock entire class/module-level dependencies in the mocha ecosystem like jest.mock?

I'm trying to unit test a module that looks something like this

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

I'm looking for something like jest.mock within the mocha ecosystem to mock the Countdown module since it has a side effect so that I can unit test this module. Sinon seems to only deal with functions, properties on objects, or object instances passed to function calls.

Upvotes: 0

Views: 1407

Answers (1)

Lin Du
Lin Du

Reputation: 102467

You can stub out ./database/orm module with link seams.

This is the CommonJS version, so we will be using proxyquire to construct our seams.

E.g.

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

unit test result:

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

Upvotes: 1

Related Questions