jestdouble

0.1.5 • Public • Published

jestdouble

jestdouble is an alternative mock/spy for jest.

npm version Build Status Coverage Status Known Vulnerabilities

Installation

$ npm install --save-dev jestdouble

Why

I wanted a mock/spy function that:

Quick start

All references to expect are jest.expect.

const jd = require('jestdouble');
 
const func = jd(); // create a jest double
 
func.returns(1, { times: 1 });
func.returns(2);
 
func(); // 1
func(); // 2
func(); // 2
 
expect(func).toHaveBeenCalledTimes(3);

Mocking results

Invoking a function

function sum(num1, num2) {
    return num1 + num2;
}
const mockedSum = jd(sum);
mockedSum(1, 2); // 3
const func = jd();
func.invokes(() => 1));
func(); // 1

Returning values

returning value

const func = jd();
func.returns(1);
func(); // 1

returning this

const object = {
  func: td()
};
object.func.returnsThis();
object.func(); // object

returning rejected error

const func = jd();
func.rejects(new Error('nope'));
func().catch((err) => {/* Error<nope> */});

returning resolved value

const func = jd();
func.resolves(1);
func().then((value) => {/* 1 */});

throwing value

const func = jd();
func.throws(new Error('nope'));
func(); // throws Error<nope>

calling back error

const func = jd();
func.callbacks(new Error('nope'));
func((err) => {/* Error<nope> */});

calling back value

const func = jd();
func.callbacks(null, 1);
func((err, value) => {/* null, 1 */});

Conditionally mocking results

calledWith

const func = jd();
func.calledWith('one').returns(1);
func(); // undefined
func('one'); // 1
func('one', 'two'); // undefined

calledStartingWith

const func = jd();
func.calledStartingWith('one').returns(1);
func(); // undefined
func('one'); // 1
func('one', 'two'); // 1

Mocking options

times

const func = jd();
func.calledWith('one').returns(1, { times: 1 });
func.returns(2, { times: 1 });
func.returns(3);
 
func('one'); // 1
func(); // 2
func('one'); // 3
func(); // 3

Verifying calls

jestdouble is compatible with jasmine assertions.

const func = jd();
func('one');
func('two');
func('three');
expect(func).toHaveBeenCalled();
expect(func).toHaveBeenCalledTimes(3);
expect(func).toHaveBeenCalledWith('one');

Conditionally verifying calls

with

const func = jd();
func('one', 'two');
expect(func.with('one')).not.toHaveBeenCalled();
expect(func.with('one', 'two')).toHaveBeenCalled();

startingWith

const func = jd();
func('one', 'two');
expect(func.startingWith('one')).toHaveBeenCalled();
expect(func.startingWith('one', 'two')).toHaveBeenCalled();

Matching

Both mocking results and verifying calls support smart value matching.

const func = jd();
func.calledWith((str) => str === 'one').returns(1);
func.calledWith(Number).returns(2);
func('one'); // 1
func(2); // 2
const func = jd();
func('two');
func('three');
expect(func.with(/^t/)).toHaveBeenCalledTimes(2);

Check the API of matchr to learn all the possibilities.

Matching options

There are three matching options.

const td = require('testdouble');
 
td.setMatchingOptions({
  matchPartialObjects: true,   // default: false
  matchPartialArrays: true,    // default: false
  matchOutOfOrderArrays: true, // default: false
});
 
const func = td();
 
func.calledWith([{ c: 3 }, { a: 1 }]).returns('OK');
 
func([{ a: 1, z: 26 }, { b: 2 }, { c: 3 }]); // 'OK'

setMatchingOptions delegates to matchr.setDefaultOptions.

API

Mock

jestdouble.invokes( arg:function [, options:object] )

jestdouble.returns( arg:* [, options:object] )

jestdouble.returnsThis( [options:object] )

jestdouble.resolves( arg:* [, options:object] )

jestdouble.rejects( arg:* [, options:object] )

jestdouble.callsback( arg:* [, options:object] ) // aliased as callbacks

jestdouble.throws( arg:* [, options:object] )

Conditional mock

jestdouble.calledWith( ...args:* ).invokes( arg:function [, options:object] )

jestdouble.calledWith( ...args:* ).returns( arg:* [, options:object] )

jestdouble.calledWith( ...args:* ).returnsThis( [options:object] )

jestdouble.calledWith( ...args:* ).resolves( arg:* [, options:object] )

jestdouble.calledWith( ...args:* ).rejects( arg:* [, options:object] )

jestdouble.calledWith( ...args:* ).callsback( arg:* [, options:object] ) // aliased as callbacks

jestdouble.calledWith( ...args:* ).throws( arg:* [, options:object] )

jestdouble.calledStartingWith( ...args:* ).invokes( arg:function [, options:object] )

jestdouble.calledStartingWith( ...args:* ) .returns( arg:* [, options:object] )

jestdouble.calledStartingWith( ...args:* ) .returnsThis( [options:object] )

jestdouble.calledStartingWith( ...args:* ) .resolves( arg:* [, options:object] )

jestdouble.calledStartingWith( ...args:* ) .rejects( arg:* [, options:object] )

jestdouble.calledStartingWith( ...args:* ) .callsback( arg:* [, options:object] ) // aliased as callbacks

jestdouble.calledStartingWith( ...args:* ) .throws( arg:* [, options:object] )

Mock options

  • times mock result N times

Verify

expect( jestdouble ).toHaveBeenCalled();

expect( jestdouble.with( ...args:* ) ).toHaveBeenCalled();

expect( jestdouble.startingWith( ...args:* ) ).toHaveBeenCalled();

Notes

Results order

Conditionally mocked results will always be returned in favour of mocked results without conditional arguments.

const func = td();
func.returns(Infinity);
func.calledWith('one').returns(1);
func(); // Infinity
func('one'); // 1
const func = td(() => 1);
func.calledWith('two').returns(2);
func(); // 1
func('two'); // 2

Credit

The name is inspired by jest and testdouble.js. API design is inspired by testdouble.js.

Package Sidebar

Install

npm i jestdouble

Weekly Downloads

1

Version

0.1.5

License

MIT

Last publish

Collaborators

  • moeriki