Jest is an amazing test runner and has some awesome assertion APIs built in by default. However there are times when having more specific matchers (assertions) would be far more convenient.
jest-extended aims to add additional matchers to Jest's default ones making it easy to test everything π
If you've come here to help contribute - Thanks! Take a look at the contributing docs as a way of getting started.
- Problem
- Solution
- Contributing
- Installation
- Setup
- Asymmetric matchers
- API
- .pass(message)
- .fail(message)
- .toBeEmpty()
- .toBeOneOf([members])
- .toBeNil()
- .toSatisfy(predicate)
- Array
- Boolean
- Date
- .toBeDate()
- .toBeValidDate()
- .toBeAfter(date)
- .toBeBefore(date)
- .toBeAfterOrEqualTo(date)
- .toBeBeforeOrEqualTo(date)
- .toBeBetween(startDate, endDate)
- Further proposals in #117 PRs welcome
- Function
- Mock
- Number
- Object
- .toBeObject()
- .toBeEmptyObject()
- .toContainKey(key)
- .toContainKeys([keys])
- .toContainAllKeys([keys])
- .toContainAnyKeys([keys])
- .toContainValue(value)
- .toContainValues([values])
- .toContainAllValues([values])
- .toContainAnyValues([values])
- .toContainEntry([key, value])
- .toContainEntries([[key, value]])
- .toContainAllEntries([[key, value]])
- .toContainAnyEntries([[key, value]])
- .toBeExtensible()
- .toBeFrozen()
- .toBeSealed()
- Promise
- String
- Symbol
- LICENSE
With npm:
npm install --save-dev jest-extended
With yarn:
yarn add -D jest-extended
Note that jest-extended
only supports Jest version 24 and newer.
// ./testSetup.js
// add all jest-extended matchers
import * as matchers from 'jest-extended';
expect.extend(matchers);
// or just add specific matchers
import { toBeArray, toBeSealed } from 'jest-extended';
expect.extend({ toBeArray, toBeSealed });
Add your setup script to your Jest setupFilesAfterEnv
configuration. See for help
"jest": {
"setupFilesAfterEnv": ["./testSetup.js"]
}
To automatically extend expect
with all matchers, you can use
"jest": {
"setupFilesAfterEnv": ["jest-extended/all"]
}
If your editor does not recognise the custom jest-extended
matchers, add a global.d.ts
file to your project with:
import 'jest-extended';
Note: When using ts-jest >= 25.5.0
Since the breaking changes in 25.5.0
you may also need to update your tsconfig.json
to include the new global.d.ts
file in the files
property like so:
{
"compilerOptions": {
...
},
...
"files": ["global.d.ts"]
}
Also note that when adding this for the first time this affects which files are compiled by the TypeScript compiler and you might need to add the include
property as well. See the TypeScript docs for more details.
If the above import syntax does not work, replace it with the following:
/// <reference types="jest-extended" />
All matchers described in the API are also asymmetrical since jest version 23:
test('passes when using an asymmetrical matcher', () => {
expect([]).toEqual(expect.toBeArray());
});
Passing assertion.
expect().pass('should pass');
Failing assertion.
expect().fail('test should fail');
Use .toBeEmpty
when checking if a String
''
, Array
[]
, Object
{}
, or Iterable
is empty. Because toBeEmpty
supports checking for emptiness of Iterables, you can use it to check whether a Map
, or Set
is empty, as well as checking that a generator yields no values.
test('passes when given an empty string', () => {
expect('').toBeEmpty();
expect('hello').not.toBeEmpty();
});
test('passes when given an empty array', () => {
expect([]).toBeEmpty();
expect(['hello']).not.toBeEmpty();
});
test('passes when given an empty object', () => {
expect({}).toBeEmpty();
expect({ hello: 'world' }).not.toBeEmpty();
});
Use .toBeOneOf
when checking if a value is a member of a given Array
.
test('passes when value is in given array', () => {
expect(1).toBeOneOf([1, 2, 3]);
expect(4).not.toBeOneOf([1, 2, 3]);
});
Use .toBeNil
when checking a value is null
or undefined
.
test('passes when value is null or undefined', () => {
expect(null).toBeNil();
expect(undefined).toBeNil();
expect(true).not.toBeNil();
});
Use .toSatisfy
when you want to use a custom matcher by supplying a predicate function that returns a Boolean
.
test('passes when value passes given predicate', () => {
const greaterThanOneButNotThree = n => n > 1 && n !== 3;
expect(100).toSatisfy(greaterThanOneButNotThree);
expect(0).not.toSatisfy(greaterThanOneButNotThree);
expect(3).not.toSatisfy(greaterThanOneButNotThree);
});
Use .toBeArray
when checking if a value is an Array
.
test('passes when value is an array', () => {
expect([]).toBeArray();
expect([1]).toBeArray();
expect(true).not.toBeArray();
});
Use .toBeArrayOfSize
when checking if a value is an Array
of size x.
test('passes when value is an array', () => {
expect([]).toBeArrayOfSize(0);
expect([1]).toBeArrayOfSize(1);
expect(true).not.toBeArrayOfSize(1);
});
Use .toIncludeAllMembers
when checking if an Array
contains all of the same members of a given set.
test('passes when given array values match the members of the set', () => {
expect([1, 2, 3]).toIncludeAllMembers([2, 1, 3]);
expect([1, 2, 2]).toIncludeAllMembers([2, 1]);
});
Use .toIncludeAllPartialMembers
when checking if an Array
contains all of the same partial members of a given set.
test('passes when given array values match the partial members of the set', () => {
expect([{ foo: 'bar', baz: 'qux' }]).toIncludeAllPartialMembers([{ foo: 'bar' }]);
});
Use .toIncludeAnyMembers
when checking if an Array
contains any of the members of a given set.
test('passes when given array values match any of the members in the set', () => {
expect([1, 2, 3]).toIncludeAnyMembers([2, 1, 3]);
expect([1, 2, 2]).toIncludeAnyMembers([2]);
expect([1, 2, 2]).not.toIncludeAnyMembers([3]);
});
Use .toIncludeSameMembers
when checking if two arrays contain equal values, in any order.
test('passes when arrays match in a different order', () => {
expect([1, 2, 3]).toIncludeSameMembers([3, 1, 2]);
expect([{ foo: 'bar' }, { baz: 'qux' }]).toIncludeSameMembers([{ baz: 'qux' }, { foo: 'bar' }]);
});
Use .toSatisfyAll
when you want to use a custom matcher by supplying a predicate function that returns a Boolean
for all values in an array.
test('passes when all values in array pass given predicate', () => {
const isOdd = el => el % 2 === 1;
expect([1, 3, 5, 7]).toSatisfyAll(isOdd);
expect([1, 3, 4, 5, 7]).not.toSatisfyAll(isOdd);
});
Use .toSatisfyAny
when you want to use a custom matcher by supplying a predicate function that returns true
for any matching value in an array.
test('passes when any value in array pass given predicate', () => {
const isOdd = el => el % 2 === 1;
expect([2, 3, 6, 8]).toSatisfyAny(isOdd);
expect([2, 4, 8, 12]).not.toSatisfyAny(isOdd);
});
Use .toBeBoolean
when checking if a value is a Boolean
.
test('passes when value is a boolean', () => {
expect(false).toBeBoolean();
expect(true).toBeBoolean();
expect(1 === 1).toBeBoolean();
expect(1).not.toBeBoolean();
});
Use .toBeTrue
when checking a value is equal (===) to true
.
test('is jest cool', () => {
expect(isJestCool()).toBeTrue();
expect(false).not.toBeTrue();
});
Use .toBeFalse
when checking a value is equal (===) to false
.
test('returns false', () => {
expect(areWeThereYet()).toBeFalse();
expect(true).not.toBeFalse();
});
Proposal in #117 (under development)
Use .toBeDate
when checking if a value is a Date
.
test('passes when value is a date', () => {
expect(new Date()).toBeDate();
expect('01/01/2018').not.toBeDate();
expect(new Date('01/01/2018')).toBeDate();
expect(undefined).not.toBeDate();
});
Use .toBeValidDate
when checking if a given Date
object is valid.
test('passes when Date is valid', () => {
expect(new Date()).toBeValidDate();
expect('01/01/2018').not.toBeValidDate();
expect(new Date('01/01/2018')).toBeValidDate();
expect(new Date('01/90/2018')).not.toBeValidDate();
expect(undefined).not.toBeValidDate();
});
Use .toBeAfter
when checking if a date occurs after date
.
test('passes when input is after date', () => {
expect(new Date('01/01/2019')).toBeAfter(new Date('01/01/2018'));
expect('01/01/2018').not.toBeAfter(new Date('01/01/2019'));
});
Use .toBeBefore
when checking if a date occurs before date
.
test('passes when input is before date', () => {
expect(new Date('01/01/2018')).toBeBefore(new Date('01/01/2019'));
expect('01/01/2019').not.toBeBefore(new Date('01/01/2018'));
});
Use .toBeAfterOrEqualTo
when checking if a date equals to or occurs after date
.
test('passes when input is equal to or after date', () => {
expect(new Date('01/01/2019')).toBeAfterOrEqualTo(new Date('01/01/2018'));
expect(new Date('01/01/2019')).toBeAfterOrEqualTo(new Date('01/01/2019'));
expect('01/01/2018').not.toBeAfterOrEqualTo(new Date('01/01/2019'));
});
Use .toBeBeforeOrEqualTo
when checking if a date equals to or occurs before date
.
test('passes when input is equal to or before date', () => {
expect(new Date('01/01/2018')).toBeBeforeOrEqualTo(new Date('01/01/2019'));
expect(new Date('01/01/2018')).toBeBeforeOrEqualTo(new Date('01/01/2018'));
expect('01/01/2019').not.toBeBeforeOrEqualTo(new Date('01/01/2018'));
});
Use .toBeBetween
when checking if a date equals or occurs after startDate
and equals or occurs before endDate
.
test('passes when input is in given date range', () => {
expect(new Date('05/01/2019')).toBeBetween(new Date('01/01/2019'), new Date('10/01/2019');
expect(new Date('05/01/2019')).toBeBetween(new Date('05/01/2019'), new Date('10/01/2019');
expect(new Date('01/01/2019')).not.toBeBetween(new Date('05/01/2019'), new Date('10/01/2019'));
});
Use .toBeFunction
when checking if a value is a Function
.
test('passes when value is a function', () => {
function noop() {}
expect(() => {}).toBeFunction();
expect(function () {}).not.toBeFunction();
expect(noop).toBeFunction();
expect(true).not.toBeFunction();
});
Use .toThrowWithMessage
when checking if a callback function throws an error with a given error type and given error message. Message can either be a String
or a RegExp
.
test('throws an error of type TypeError with message "hello world"', () => {
expect(() => {
throw TypeError('hello world');
}).toThrowWithMessage(TypeError, 'hello world');
expect(() => {
throw TypeError('hello world');
}).toThrowWithMessage(TypeError, /hello world/);
expect(() => {
throw TypeError('hello world 2');
}).not.toThrowWithMessage(TypeError, 'hello world');
expect(() => {
throw TypeError('hello world 2');
}).not.toThrowWithMessage(TypeError, /hello world/);
});
This works for promise rejections too.
test('throws an error of type TypeError with message "hello world"', async () => {
await expect(Promise.reject(new TypeError("hello world async")).rejects.toThrowWithMessage(TypeError, /hello world/);
});
Use .toHaveBeenCalledBefore
when checking if a Mock
was called before another Mock
.
Note: Required Jest version >=23
it('calls mock1 before mock2', () => {
const mock1 = jest.fn();
const mock2 = jest.fn();
mock1();
mock2();
mock1();
expect(mock1).toHaveBeenCalledBefore(mock2);
});
Use .toHaveBeenCalledAfter
when checking if a Mock
was called after another Mock
.
Note: Required Jest version >=23
it('calls mock1 after mock2', () => {
const mock1 = jest.fn();
const mock2 = jest.fn();
mock2();
mock1();
mock2();
expect(mock1).toHaveBeenCalledAfter(mock2);
});
Use .toHaveBeenCalledOnce
to check if a Mock
was called exactly one time.
it('passes only if mock was called exactly once', () => {
const mock = jest.fn();
expect(mock).not.toHaveBeenCalled();
mock();
expect(mock).toHaveBeenCalledOnce();
});
Use .toBeNumber
when checking if a value is a Number
.
test('passes when value is a number', () => {
expect(1).toBeNumber();
expect(NaN).toBeNumber();
expect(Infinity).toBeNumber();
expect(true).not.toBeNumber();
});
Use .toBeNaN
when checking a value is NaN
.
test('passes when value is NaN', () => {
expect(NaN).toBeNaN();
expect(1).not.toBeNaN();
});
Use .toBeFinite
when checking if a value is a Number
, not NaN
or Infinity
.
test('passes when value is a finite number', () => {
expect(1).toBeFinite();
expect(Infinity).not.toBeFinite();
expect(NaN).not.toBeFinite();
});
Use .toBePositive
when checking if a value is a positive Number
.
test('passes when value is a positive number', () => {
expect(1).toBePositive();
expect(Infinity).not.toBePositive();
expect(-1).not.toBePositive();
expect(NaN).not.toBePositive();
});
Use .toBeNegative
when checking if a value is a negative Number
.
test('passes when value is a negative number', () => {
expect(-1).toBeNegative();
expect(-Infinity).not.toBeNegative();
expect(1).not.toBeNegative();
expect(NaN).not.toBeNegative();
});
Use .toBeEven
when checking if a value is an even Number
.
test('passes when value is an even number', () => {
expect(2).toBeEven();
expect(1).not.toBeEven();
expect(NaN).not.toBeEven();
});
Use .toBeOdd
when checking if a value is an odd Number
.
test('passes when value is an odd number', () => {
expect(1).toBeOdd();
expect(2).not.toBeOdd();
expect(NaN).not.toBeOdd();
});
Use .toBeWithin
when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive).
test('passes when number is within given bounds', () => {
expect(1).toBeWithin(1, 3);
expect(2).toBeWithin(1, 3);
expect(3).not.toBeWithin(1, 3);
});
Use .toBeInteger
when checking if a number is an integer.
test('passes when value is an integer', () => {
expect(1).toBeInteger();
expect(1.0).toBeInteger();
expect(1.1).not.toBeInteger();
});
Use .toBeEmptyObject
when checking if a value is an empty Object
.
test('passes when value is an empty object', () => {
expect({}).toBeEmptyObject();
expect({ a: 'hello' }).not.toBeEmptyObject();
});
Use .toBeObject
when checking if a value is an Object
.
test('passes when value is an object', () => {
expect({}).toBeObject();
expect({ a: 'hello' }).toBeObject();
expect(true).not.toBeObject();
});
Use .toContainKey
when checking if an object contains the provided key.
test('passes when object contains the given key', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainKey('a');
expect(o).toContainKey('b');
expect(o).toContainKey('c');
expect(o).not.toContainKey('d');
});
Use .toContainKeys
when checking if an object has all of the provided keys.
test('passes when object contains all keys', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainKeys(['a', 'b']);
expect(o).toContainKeys(['b', 'c']);
expect(o).not.toContainKeys(['d']);
});
Use .toContainAllKeys
when checking if an object only contains all of the provided keys.
test('passes when object only contains all keys', () => {
const o = { a: 'hello', b: 'world' };
expect(o).toContainAllKeys(['a', 'b']);
expect(o).toContainAllKeys(['b', 'a']);
expect(o).not.toContainAllKeys(['b']);
});
Use .toContainAnyKeys
when checking if an object contains at least one of the provided keys.
test('passes when object contains at least one matching key', () => {
const o = { a: 'hello', b: 'world' };
expect(o).toContainAnyKeys(['a']);
expect(o).toContainAnyKeys(['b']);
expect(o).toContainAnyKeys(['b', 'c']);
expect(o).not.toContainAnyKeys(['c']);
});
Use .toContainValue
when checking if an object contains the provided value.
test('passes when object contains given value', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainValue('foo');
expect(o).toContainValue('bar');
expect(o).not.toContainValue('qux');
});
Use .toContainValues
when checking if an object contains all of the provided values.
test('passes when object contains all of the given values', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainValues(['foo']);
expect(o).toContainValues(['baz', 'bar']);
expect(o).not.toContainValues(['qux', 'foo']);
});
Use .toContainAllValues
when checking if an object only contains all of the provided values.
test('passes when object only contains all of the given values', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainAllValues(['foo', 'bar', 'baz']);
expect(o).toContainAllValues(['baz', 'bar', 'foo']);
expect(o).not.toContainAllValues(['bar', 'foo']);
});
Use .toContainAnyValues
when checking if an object contains at least one of the provided values.
test('passes when object contains at least one of the given values', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainAnyValues(['qux', 'foo']);
expect(o).toContainAnyValues(['qux', 'bar']);
expect(o).toContainAnyValues(['qux', 'baz']);
expect(o).not.toContainAnyValues(['qux']);
});
Use .toContainEntry
when checking if an object contains the provided entry.
test('passes when object contains given entry', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainEntry(['a', 'foo']);
expect(o).toContainEntry(['b', 'bar']);
expect(o).toContainEntry(['c', 'baz']);
expect(o).not.toContainEntry(['a', 'qux']);
});
Use .toContainEntries
when checking if an object contains all of the provided entries.
test('passes when object contains all of the given entries', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainEntries([['a', 'foo']]);
expect(o).toContainEntries([
['c', 'baz'],
['a', 'foo'],
]);
expect(o).not.toContainEntries([
['b', 'qux'],
['a', 'foo'],
]);
});
Use .toContainAllEntries
when checking if an object only contains all of the provided entries.
test('passes when object only contains all of the given entries', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainAllEntries([
['a', 'foo'],
['b', 'bar'],
['c', 'baz'],
]);
expect(o).not.toContainAllEntries([
['a', 'foo'],
['b', 'bar'],
]);
});
Use .toContainAnyEntries
when checking if an object contains at least one of the provided entries.
test('passes when object contains at least one of the given entries', () => {
const o = { a: 'foo', b: 'bar', c: 'baz' };
expect(o).toContainAnyEntries([
['a', 'qux'],
['a', 'foo'],
]);
expect(o).toContainAnyEntries([
['a', 'qux'],
['b', 'bar'],
]);
expect(o).toContainAnyEntries([
['a', 'qux'],
['c', 'baz'],
]);
expect(o).not.toContainAnyEntries([['d', 'qux']]);
});
Use .toBeExtensible
when checking if an object is extensible.
test('passes when value is extensible', () => {
expect({ a: 1 }).toBeExtensible();
expect(1).not.toBeExtensible();
});
Use .toBeFrozen
when checking if an object is frozen.
test('passes when value is frozen', () => {
expect(Object.frozen({})).toBeFrozen();
expect({}).not.toBeFrozen();
expect(1).not.toBeFrozen();
});
Use .toBeSealed
when checking if an object is sealed.
test('passes when value is sealed', () => {
expect(Object.seal({})).toBeSealed();
expect({}).not.toBeSealed();
expect(1).not.toBeSealed();
});
Use .toResolve
when checking if a promise is resolved.
test('passes when a promise resolves', async () => {
await expect(Promise.resolve()).toResolve();
});
Use .toReject
when checking if a promise is rejected.
test('passes when a promise rejects', async () => {
await expect(Promise.reject()).toReject();
});
Use .toBeString
when checking if a value is a String
.
test('passes when value is a string', () => {
expect('').toBeString();
expect('hello').toBeString();
expect(new String('hello')).toBeString();
expect(true).not.toBeString();
});
Use .toBeHexadecimal
when checking if a value is a valid HTML hexadecimal color.
test('passes when value is a valid hexadecimal', () => {
expect('#abc123').toBeHexadecimal();
expect('#FFF').toBeHexadecimal();
expect('#000000').toBeHexadecimal();
expect('#123ffg').not.toBeHexadecimal();
});
Use .toBeDateString
when checking if a value is a valid date string.
test('passes when value is a valid toBeDateString', () => {
expect('2019-11-27T14:05:07.520Z').toBeDateString();
expect('11/12/21').toBeDateString();
expect('not a date').not.toBeDateString();
});
Use .toEqualCaseInsensitive
when checking if a string is equal (===) to another ignoring the casing of both strings.
test('passes when strings are equal ignoring case', () => {
expect('hello world').toEqualCaseInsensitive('hello world');
expect('hello WORLD').toEqualCaseInsensitive('HELLO world');
expect('HELLO WORLD').toEqualCaseInsensitive('hello world');
expect('hello world').toEqualCaseInsensitive('HELLO WORLD');
expect('hello world').not.toEqualCaseInsensitive('hello');
});
Use .toStartWith
when checking if a String
starts with a given String
prefix.
test('passes when value is starts with given string', () => {
expect('hello world').toStartWith('hello');
expect('hello world').not.toStartWith('world');
});
Use .toEndWith
when checking if a String
ends with a given String
suffix.
test('passes when value is ends with given string', () => {
expect('hello world').toEndWith('world');
expect('hello world').not.toEndWith('hello');
});
Use .toInclude
when checking if a String
includes the given String
substring.
test('passes when value includes substring', () => {
expect('hello world').toInclude('ell');
expect('hello world').not.toInclude('bob');
});
Use .toIncludeRepeated
when checking if a String
includes the given String
substring the correct number of times.
test('passes when value includes substring n times', () => {
expect('hello hello world').toIncludeRepeated('hello', 2);
expect('hello hello world').not.toIncludeRepeated('hello', 1);
});
Use .toIncludeMultiple
when checking if a String
includes all of the given substrings.
test('passes when value includes all substrings', () => {
expect('hello world').toIncludeMultiple(['world', 'hello']);
expect('hello world').not.toIncludeMultiple(['world', 'hello', 'bob']);
});
Use .toBeSymbol
when checking if a value is a Symbol
.
test('passes when value is a symbol', () => {
expect(Symbol()).toBeSymbol();
expect(true).not.toBeSymbol();
});