Have ideas to improve npm?Join in the discussion! »

    to-mock

    1.6.2 • Public • Published

    to-mock

    Build Status Dependency Status Coverage Status NPM package version code style: prettier Snyk Vulnerabilities for npm package

    The to-mock module help you with creating mocked classes and objects. So your tests are up to date with your defined classes because you don't have to keep mocks or interface for your tests. Then you can creating the unit tests for interface and not for implementation detail, your tests are more isolated and you can easy creating real unit tests.

    The javascript to-mock module can be used with any test framework like jest, ava, tape, jasmine, mocha and others. Even you may use it for mocking in typescript. Those are other benefits for your unit tests because you can change test framework or language.

    You can mock Date, RegExp and other native object.

    Installation

    You can add the to-mock to your project or testing tools using npm:

    npm i to-mock --save-dev

    Examples

    1. Jasmine - example with jasmine and toMockedInstance
    2. Jest/Typescript - example with jest and typescript
    3. AVA - example with ava and self testing
    4. Best practice - example with setting to-mock module for jest framework

    API

    1. toMock
    2. toMockedInstance
    3. setGlobalKeepUnmock
    4. setGlobalMockMethod

    Usage

    The library is designed to be used in ES2015 environment. For older node <6 you must use babel and for older browser use browserify with babel.

    // MyArray.js
    export default class MyArray {
      constructor(array) {
        this.array = array.slice();
      }
     
      clone() {
        return this.array.slice();
      }
    }
     
    //MyArraySpec.js
    import MyArray from './MyArray';
    import toMock from 'to-mock';
     
    describe('Your spec', () => {
     
      // The MyArray class is not modified
      const MockedMyArray = toMock(MyArray);
      //class MockedMyArray {
      // constructor() {}
      // clone() {}
      //}
      const mockedInstance = new MockedMyArray();
     
      it('is instance of MyArray', () => {
        expect(mockedInstance instanceof MyArray).toBeTruthy();
      });
     
      it('method not throw Error', () => {
        expect(() => mockedInstance.clone()).not.toThrow();
      });
    });

    Mock native object

    Example with overriding native Date object.

    //MyDateSpec.js
    import toMock from 'to-mock';
     
    describe('Your spec', () => {
     
      const MockedDate = toMock(Date);
      const RealDate = Date;
     
      beforeEach(() => {
        Date = MockedDate;
      });
     
      afterEach(() => {
        Date = RealDate;
      };)
     
      it('you can mock date', () => {
        spyOn(MockedDate, 'now').and.returnValue(1);
     
        expect(Date.now()).toEqual(1);
      });
    });

    toMockedInstance

    Sometimes you want to working with mocked instance which will be defined some default values. You can use of course toMock function for that but better solution is use toMockedInstance function.

    //MyDateSpec.js
    import toMock, { toMockedInstance } from 'to-mock';
     
    describe('Your spec', () => {
     
      it('you can create mocked instance of date', () => {
        //let MockedDate = toMock(Date);
        //let date = new MockedDate();
        //let dateWithDefault = Object.assign(
        //  date,
        //  { getTime: () => 1 }
        //);
     
        const dateWithDefault = toMockedInstance(
          Date,
          { getTime: () => 1 }
        );
     
        expect(dateWithDefault.getTime()).toEqual(1);
      });
    });

    setGlobalKeepUnmock

    You want to working with unmocked methods and properties in very rare use case. For that case you can used globalKeepUnmock method or defined keepUnmock callback as other argument.

    //MyDateSpec.js
    import toMock, { toMockedInstance, setGlobalKeepUnmock } from 'to-mock';
     
    describe('Your spec', () => {
     
      it('you can create mocked instance of date', () => {
        function keepUnmock({ property, descriptor, original, mock }) {
          return property === 'getDay';
        }
     
        //let MockedDate = toMock(Date, keepUnmock);
        //or    
        //let MockedDate = toMock(Date);
        //setGlobalKeepUnmock(keepUnmock);
     
        //let date = new MockedDate();
        //let dateWithDefault = Object.assign(
        //  date,
        //  { getTime: () => 1 }
        //);
     
        let dateWithDefault = toMockedInstance(
          Date,
          { getTime: () => 1 },
          keepUnmock
        );
     
        let dayFromMock = Reflect.apply(
          dateWithDefault.getDay,
          new Date(),
          []
        );
        let dayFromDate = new Date().getDay();
     
     
        expect(dateWithDefault.getTime()).toEqual(1);
        expect(dayFromMock === dateFromDate).toEqual(true);
      });
    });

    setGlobalMockMethod

    You can define a specific mock function used for all method mocks. This way, you can replace all these methods with jest.fn, or any other mock method, depending on your testing framework.

    //MyDateSpec.js
    import { toMockedInstance, setGlobalMockMethod } from 'to-mock';
     
    describe('Your spec', () => {
     
      it('you can create mocked instance of date', () => {
        setGlobalMockMethod(jest.fn);
     
        let date = toMockedInstance(Date);
        date.getTime();
     
        // You can use all jest.fn() related methods now
        expect(date.getTime).toHaveBeenCalled();
      });
    });

    Typescript

    Sometimes you need mock all methods in file and sometimes you need original method for some use cases. For example: Jest have method mockFn.mockRestore for restoring original method but it throws error for typescript. Luckily to-mock module will help you. You can see source code

    //indexSpec.ts
     
    import { setGlobalMockMethod, toMockedInstance } from 'to-mock';
    import * as utils from '../utils';
     
    //jest.mock('../utils');
    //utils.once.mockRestore(); // throw Error in Typescript
     
    jest.mock('../utils', () => {
      const original = jest.requireActual('../utils');
     
      setGlobalMockMethod(jest.fn);
     
      return toMockedInstance(
        original,
        { __original__: original },
        ({ property }) => property === 'once'
      );
    });

    Best practice

    We use to-mock module for unit tests and integration tests in large applications. We share you our setup file for jest framework which you can configure through setupFiles.

    // setupJest.js
     
    import {
      objectKeepUnmock,
      setGlobalKeepUnmock,
      setGlobalMockMethod
    } from 'to-mock';
     
    // every method is replaced to jest.fn()
    setGlobalMockMethod(jest.fn);
    // native object method keep unmock
    setGlobalKeepUnmock(objectKeepUnmock);
     
     
    // *Spec.js
    import { toMockedInstance } from 'to-mock';
     
    // we use toMockedInstance almost everywhere

    Contributing

    Contributing to this repository is done via Pull-Requests. Any commit that you make must follow simple rules that are automatically validated upon committing.

    1. type of change (build, ci, chore, docs, feat, fix, perf, refactor, revert, style, test)
    2. scope of change in brackets ( ... ). This should be one-word description of what part of the repository you've changed.
    3. colon :
    4. message (lower-case)

    fix(iframe): message

    feat(loader): message

    To simplify this process you can use npm run commit command that will interactively prompt for details and will also run linter before you commit. For more information see commitizen/cz-cli repository.

    Install

    npm i to-mock

    DownloadsWeekly Downloads

    3

    Version

    1.6.2

    License

    MIT

    Unpacked Size

    18 kB

    Total Files

    5

    Last publish

    Collaborators

    • avatar