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.

Package Sidebar

Install

npm i to-mock

Weekly Downloads

67

Version

1.6.2

License

MIT

Unpacked Size

18 kB

Total Files

5

Last publish

Collaborators

  • mjancarik