jestdouble
v0.1.5
Published
An alternative mock/spy for jest
Downloads
7
Maintainers
Readme
- Installation
- Why
- Quick start
- Mocking results
- Conditionally mocking results
- Verifying calls
- Conditionally verifying calls
- Matching
- Notes
- Credit
Installation
$ npm install --save-dev jestdouble
Why
I wanted a mock/spy function that:
- could conditionally mock results / verify calls
- had smart value matching enabled by default
- was compatible with jasmine assertions
- had an awesome API
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.