Skip to content

C#-like API for creating mock in TypeScript for Node.js environment

License

Notifications You must be signed in to change notification settings

bacebu4/interface-mock

Repository files navigation

npm version tests

Interface Mock

C#-like API for creating mock in TypeScript for Node.js environment

Installation

npm install --save-dev interface-mock

or

yarn add --dev interface-mock

Usage

Create mock by passing interface to it and providing default implementation, then call .verify() method to check whether the method was called. Additionally you can specify how many times it should have been called

import { createInterfaceMock } from 'interface-mock';

interface IBus {
  send: (message: string) => Promise<void>;
}

describe('SomeTest', () => {
  it('works', () => {
    const busMock = createInterfaceMock<IBus>({ send: async () => {} });
    const someService = new SomeService(busMock);

    someService.execute();

    busMock.verify(m => m.send('Hello'));
  });

  it('works 2', () => {
    const busMock = createInterfaceMock<IBus>({ send: async () => {} });
    const someService = new SomeService(busMock);

    someService.execute();

    busMock.verify(m => m.send('Hello'), { times: 2 });
  });
});

Additionally you can manually specify the resulting type of createInterfaceMock function:

import { createInterfaceMock, InterfaceMock } from 'interface-mock';

interface IBus {
  send: (message: string) => Promise<void>;
}

describe('SomeTest', () => {
  let busMock: InterfaceMock<IBus>;

  beforeEach(() => {
    busMock = createInterfaceMock<IBus>({ send: async () => {} });
  });

  it('works', () => {
    const someService = new SomeService(busMock);

    someService.execute();

    busMock.verify(m => m.send('Hello'));
  });
});

Motivation

Without the library, the code above would look like this:

import { mock } from 'node:test';
import { assert } from 'node:assert';

interface IBus {
  send: (message: string) => Promise<void>;
}

describe('SomeTest', () => {
  it('works', () => {
    const busMock = { send: mock.fn(async () => ({})) };
    const someService = new SomeService(busMock);

    someService.execute();

    const args = busMock.mock.calls.at(0)?.arguments;
    assert.deepStrictEqual(args, ['Hello']);
    assert.strictEqual(busMock.mock.calls.length, 1);
  });
});

Additionally, using the approach above complicates the process of checking mock calls when they are made multiple times:

busMock.send('1');
busMock.send('2');

and then verifying that it was called once with specific arguments, which can be done more simply using the library:

busMock.verify(b => b.send('2'));

While this case is relatively rare, the main motivation for using this library is to improve the readability and simplicity of writing tests. By using the library, test code becomes more declarative and concise, allowing developers to focus on intent rather than boilerplate logic for call tracking.

About

C#-like API for creating mock in TypeScript for Node.js environment

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published