BDD
The BDD styles are expect
and should
. Both use the same chainable language to
construct assertions, but they differ in the way an assertion is initially constructed.
Check out the Style Guide for a comparison.
API Reference
Language Chains
The following are provided as chainable getters to improve the readability of your assertions.
Chains
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
- still
- also
.not
Negates all assertions that follow in the chain.
expect(function () {}).to.not.throw();
expect({a: 1}).to.not.have.property('b');
expect([1, 2]).to.be.an('array').that.does.not.include(3);
Just because you can negate any assertion with .not
doesn’t mean you
should. With great power comes great responsibility. It’s often best to
assert that the one expected output was produced, rather than asserting
that one of countless unexpected outputs wasn’t produced. See individual
assertions for specific guidance.
expect(2).to.equal(2); // Recommended
expect(2).to.not.equal(1); // Not recommended
.deep
Causes all .equal
, .include
, .members
, .keys
, and .property
assertions that follow in the chain to use deep equality instead of strict
(===
) equality. See the deep-eql
project page for info on the deep
equality algorithm: https://github.com/chaijs/deep-eql.
// Target object deeply (but not strictly) equals `{a: 1}`
expect({a: 1}).to.deep.equal({a: 1});
expect({a: 1}).to.not.equal({a: 1});
// Target array deeply (but not strictly) includes `{a: 1}`
expect([{a: 1}]).to.deep.include({a: 1});
expect([{a: 1}]).to.not.include({a: 1});
// Target object deeply (but not strictly) includes `x: {a: 1}`
expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
expect({x: {a: 1}}).to.not.include({x: {a: 1}});
// Target array deeply (but not strictly) has member `{a: 1}`
expect([{a: 1}]).to.have.deep.members([{a: 1}]);
expect([{a: 1}]).to.not.have.members([{a: 1}]);
// Target set deeply (but not strictly) has key `{a: 1}`
expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]);
expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]);
// Target object deeply (but not strictly) has property `x: {a: 1}`
expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
.nested
Enables dot- and bracket-notation in all .property
and .include
assertions that follow in the chain.
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
If .
or []
are part of an actual property name, they can be escaped by
adding two backslashes before them.
expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
.nested
cannot be combined with .own
.
.own
Causes all .property
and .include
assertions that follow in the chain
to ignore inherited properties.
Object.prototype.b = 2;
expect({a: 1}).to.have.own.property('a');
expect({a: 1}).to.have.property('b');
expect({a: 1}).to.not.have.own.property('b');
expect({a: 1}).to.own.include({a: 1});
expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
.own
cannot be combined with .nested
.
.ordered
Causes all .members
assertions that follow in the chain to require that
members be in the same order.
expect([1, 2]).to.have.ordered.members([1, 2])
.but.not.have.ordered.members([2, 1]);
When .include
and .ordered
are combined, the ordering begins at the
start of both arrays.
expect([1, 2, 3]).to.include.ordered.members([1, 2])
.but.not.include.ordered.members([2, 3]);
.any
Causes all .keys
assertions that follow in the chain to only require that
the target have at least one of the given keys. This is the opposite of
.all
, which requires that the target have all of the given keys.
expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
See the .keys
doc for guidance on when to use .any
or .all
.
.all
Causes all .keys
assertions that follow in the chain to require that the
target have all of the given keys. This is the opposite of .any
, which
only requires that the target have at least one of the given keys.
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
Note that .all
is used by default when neither .all
nor .any
are
added earlier in the chain. However, it’s often best to add .all
anyway
because it improves readability.
See the .keys
doc for guidance on when to use .any
or .all
.
.a(type[, msg])
Asserts that the target’s type is equal to the given string type
. Types
are case insensitive. See the type-detect
project page for info on the
type detection algorithm: https://github.com/chaijs/type-detect.
expect('foo').to.be.a('string');
expect({a: 1}).to.be.an('object');
expect(null).to.be.a('null');
expect(undefined).to.be.an('undefined');
expect(new Error).to.be.an('error');
expect(Promise.resolve()).to.be.a('promise');
expect(new Float32Array).to.be.a('float32array');
expect(Symbol()).to.be.a('symbol');
.a
supports objects that have a custom type set via Symbol.toStringTag
.
var myObj = {
[Symbol.toStringTag]: 'myCustomType'
};
expect(myObj).to.be.a('myCustomType').but.not.an('object');
It’s often best to use .a
to check a target’s type before making more
assertions on the same target. That way, you avoid unexpected behavior from
any assertion that does different things based on the target’s type.
expect([1, 2, 3]).to.be.an('array').that.includes(2);
expect([]).to.be.an('array').that.is.empty;
Add .not
earlier in the chain to negate .a
. However, it’s often best to
assert that the target is the expected type, rather than asserting that it
isn’t one of many unexpected types.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.an('array'); // Not recommended
.a
accepts an optional msg
argument which is a custom error message to
show when the assertion fails. The message can also be given as the second
argument to expect
.
expect(1).to.be.a('string', 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.a('string');
.a
can also be used as a language chain to improve the readability of
your assertions.
expect({b: 2}).to.have.a.property('b');
The alias .an
can be used interchangeably with .a
.
.include(val[, msg])
When the target is a string, .include
asserts that the given string val
is a substring of the target.
expect('foobar').to.include('foo');
When the target is an array, .include
asserts that the given val
is a
member of the target.
expect([1, 2, 3]).to.include(2);
When the target is an object, .include
asserts that the given object
val
’s properties are a subset of the target’s properties.
expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
When the target is a Set or WeakSet, .include
asserts that the given val
is a
member of the target. SameValueZero equality algorithm is used.
expect(new Set([1, 2])).to.include(2);
When the target is a Map, .include
asserts that the given val
is one of
the values of the target. SameValueZero equality algorithm is used.
expect(new Map([['a', 1], ['b', 2]])).to.include(2);
Because .include
does different things based on the target’s type, it’s
important to check the target’s type before using .include
. See the .a
doc for info on testing a target’s type.
expect([1, 2, 3]).to.be.an('array').that.includes(2);
By default, strict (===
) equality is used to compare array members and
object properties. Add .deep
earlier in the chain to use deep equality
instead (WeakSet targets are not supported). See the deep-eql
project
page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
// Target array deeply (but not strictly) includes `{a: 1}`
expect([{a: 1}]).to.deep.include({a: 1});
expect([{a: 1}]).to.not.include({a: 1});
// Target object deeply (but not strictly) includes `x: {a: 1}`
expect({x: {a: 1}}).to.deep.include({x: {a: 1}});
expect({x: {a: 1}}).to.not.include({x: {a: 1}});
By default, all of the target’s properties are searched when working with
objects. This includes properties that are inherited and/or non-enumerable.
Add .own
earlier in the chain to exclude the target’s inherited
properties from the search.
Object.prototype.b = 2;
expect({a: 1}).to.own.include({a: 1});
expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
Note that a target object is always only searched for val
’s own
enumerable properties.
.deep
and .own
can be combined.
expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
Add .nested
earlier in the chain to enable dot- and bracket-notation when
referencing nested properties.
expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
If .
or []
are part of an actual property name, they can be escaped by
adding two backslashes before them.
expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
.deep
and .nested
can be combined.
expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
.own
and .nested
cannot be combined.
Add .not
earlier in the chain to negate .include
.
expect('foobar').to.not.include('taco');
expect([1, 2, 3]).to.not.include(4);
However, it’s dangerous to negate .include
when the target is an object.
The problem is that it creates uncertain expectations by asserting that the
target object doesn’t have all of val
’s key/value pairs but may or may
not have some of them. It’s often best to identify the exact output that’s
expected, and then write an assertion that only accepts that exact output.
When the target object isn’t even expected to have val
’s keys, it’s
often best to assert exactly that.
expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
When the target object is expected to have val
’s keys, it’s often best to
assert that each of the properties has its expected value, rather than
asserting that each property doesn’t have one of many unexpected values.
expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended
expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended
.include
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect([1, 2, 3]).to.include(4, 'nooo why fail??');
expect([1, 2, 3], 'nooo why fail??').to.include(4);
.include
can also be used as a language chain, causing all .members
and
.keys
assertions that follow in the chain to require the target to be a
superset of the expected set, rather than an identical set. Note that
.members
ignores duplicates in the subset when .include
is added.
// Target object's keys are a superset of ['a', 'b'] but not identical
expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
// Target array is a superset of [1, 2] but not identical
expect([1, 2, 3]).to.include.members([1, 2]);
expect([1, 2, 3]).to.not.have.members([1, 2]);
// Duplicates in the subset are ignored
expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
Note that adding .any
earlier in the chain causes the .keys
assertion
to ignore .include
.
// Both assertions are identical
expect({a: 1}).to.include.any.keys('a', 'b');
expect({a: 1}).to.have.any.keys('a', 'b');
The aliases .includes
, .contain
, and .contains
can be used
interchangeably with .include
.
.ok
Asserts that the target is a truthy value (considered true
in boolean context).
However, it’s often best to assert that the target is strictly (===
) or
deeply equal to its expected value.
expect(1).to.equal(1); // Recommended
expect(1).to.be.ok; // Not recommended
expect(true).to.be.true; // Recommended
expect(true).to.be.ok; // Not recommended
Add .not
earlier in the chain to negate .ok
.
expect(0).to.equal(0); // Recommended
expect(0).to.not.be.ok; // Not recommended
expect(false).to.be.false; // Recommended
expect(false).to.not.be.ok; // Not recommended
expect(null).to.be.null; // Recommended
expect(null).to.not.be.ok; // Not recommended
expect(undefined).to.be.undefined; // Recommended
expect(undefined).to.not.be.ok; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(false, 'nooo why fail??').to.be.ok;
.true
Asserts that the target is strictly (===
) equal to true
.
expect(true).to.be.true;
Add .not
earlier in the chain to negate .true
. However, it’s often best
to assert that the target is equal to its expected value, rather than not
equal to true
.
expect(false).to.be.false; // Recommended
expect(false).to.not.be.true; // Not recommended
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.true; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(false, 'nooo why fail??').to.be.true;
.false
Asserts that the target is strictly (===
) equal to false
.
expect(false).to.be.false;
Add .not
earlier in the chain to negate .false
. However, it’s often
best to assert that the target is equal to its expected value, rather than
not equal to false
.
expect(true).to.be.true; // Recommended
expect(true).to.not.be.false; // Not recommended
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.false; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(true, 'nooo why fail??').to.be.false;
.null
Asserts that the target is strictly (===
) equal to null
.
expect(null).to.be.null;
Add .not
earlier in the chain to negate .null
. However, it’s often best
to assert that the target is equal to its expected value, rather than not
equal to null
.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.null; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(42, 'nooo why fail??').to.be.null;
.undefined
Asserts that the target is strictly (===
) equal to undefined
.
expect(undefined).to.be.undefined;
Add .not
earlier in the chain to negate .undefined
. However, it’s often
best to assert that the target is equal to its expected value, rather than
not equal to undefined
.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.undefined; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(42, 'nooo why fail??').to.be.undefined;
.NaN
Asserts that the target is exactly NaN
.
expect(NaN).to.be.NaN;
Add .not
earlier in the chain to negate .NaN
. However, it’s often best
to assert that the target is equal to its expected value, rather than not
equal to NaN
.
expect('foo').to.equal('foo'); // Recommended
expect('foo').to.not.be.NaN; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(42, 'nooo why fail??').to.be.NaN;
.exist
Asserts that the target is not strictly (===
) equal to either null
or
undefined
. However, it’s often best to assert that the target is equal to
its expected value.
expect(1).to.equal(1); // Recommended
expect(1).to.exist; // Not recommended
expect(0).to.equal(0); // Recommended
expect(0).to.exist; // Not recommended
Add .not
earlier in the chain to negate .exist
.
expect(null).to.be.null; // Recommended
expect(null).to.not.exist; // Not recommended
expect(undefined).to.be.undefined; // Recommended
expect(undefined).to.not.exist; // Not recommended
A custom error message can be given as the second argument to expect
.
expect(null, 'nooo why fail??').to.exist;
The alias .exists
can be used interchangeably with .exist
.
.empty
When the target is a string or array, .empty
asserts that the target’s
length
property is strictly (===
) equal to 0
.
expect([]).to.be.empty;
expect('').to.be.empty;
When the target is a map or set, .empty
asserts that the target’s size
property is strictly equal to 0
.
expect(new Set()).to.be.empty;
expect(new Map()).to.be.empty;
When the target is a non-function object, .empty
asserts that the target
doesn’t have any own enumerable properties. Properties with Symbol-based
keys are excluded from the count.
expect({}).to.be.empty;
Because .empty
does different things based on the target’s type, it’s
important to check the target’s type before using .empty
. See the .a
doc for info on testing a target’s type.
expect([]).to.be.an('array').that.is.empty;
Add .not
earlier in the chain to negate .empty
. However, it’s often
best to assert that the target contains its expected number of values,
rather than asserting that it’s not empty.
expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
expect([1, 2, 3]).to.not.be.empty; // Not recommended
expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended
expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended
expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended
expect({a: 1}).to.not.be.empty; // Not recommended
A custom error message can be given as the second argument to expect
.
expect([1, 2, 3], 'nooo why fail??').to.be.empty;
.arguments
Asserts that the target is an arguments
object.
function test () {
expect(arguments).to.be.arguments;
}
test();
Add .not
earlier in the chain to negate .arguments
. However, it’s often
best to assert which type the target is expected to be, rather than
asserting that it’s not an arguments
object.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.arguments; // Not recommended
A custom error message can be given as the second argument to expect
.
expect({}, 'nooo why fail??').to.be.arguments;
The alias .Arguments
can be used interchangeably with .arguments
.
.equal(val[, msg])
Asserts that the target is strictly (===
) equal to the given val
.
expect(1).to.equal(1);
expect('foo').to.equal('foo');
Add .deep
earlier in the chain to use deep equality instead. See the
deep-eql
project page for info on the deep equality algorithm:
https://github.com/chaijs/deep-eql.
// Target object deeply (but not strictly) equals `{a: 1}`
expect({a: 1}).to.deep.equal({a: 1});
expect({a: 1}).to.not.equal({a: 1});
// Target array deeply (but not strictly) equals `[1, 2]`
expect([1, 2]).to.deep.equal([1, 2]);
expect([1, 2]).to.not.equal([1, 2]);
Add .not
earlier in the chain to negate .equal
. However, it’s often
best to assert that the target is equal to its expected value, rather than
not equal to one of countless unexpected values.
expect(1).to.equal(1); // Recommended
expect(1).to.not.equal(2); // Not recommended
.equal
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(1).to.equal(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.equal(2);
The aliases .equals
and eq
can be used interchangeably with .equal
.
.eql(obj[, msg])
Asserts that the target is deeply equal to the given obj
. See the
deep-eql
project page for info on the deep equality algorithm:
https://github.com/chaijs/deep-eql.
// Target object is deeply (but not strictly) equal to {a: 1}
expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1});
// Target array is deeply (but not strictly) equal to [1, 2]
expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]);
Add .not
earlier in the chain to negate .eql
. However, it’s often best
to assert that the target is deeply equal to its expected value, rather
than not deeply equal to one of countless unexpected values.
expect({a: 1}).to.eql({a: 1}); // Recommended
expect({a: 1}).to.not.eql({b: 2}); // Not recommended
.eql
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
The alias .eqls
can be used interchangeably with .eql
.
The .deep.equal
assertion is almost identical to .eql
but with one
difference: .deep.equal
causes deep equality comparisons to also be used
for any other assertions that follow in the chain.
.above(n[, msg])
Asserts that the target is a number or a date greater than the given number or date n
respectively.
However, it’s often best to assert that the target is equal to its expected
value.
expect(2).to.equal(2); // Recommended
expect(2).to.be.above(1); // Not recommended
Add .lengthOf
earlier in the chain to assert that the target’s length
or size
is greater than the given number n
.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.have.lengthOf.above(2); // Not recommended
expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended
Add .not
earlier in the chain to negate .above
.
expect(2).to.equal(2); // Recommended
expect(1).to.not.be.above(2); // Not recommended
.above
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(1).to.be.above(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.above(2);
The aliases .gt
and .greaterThan
can be used interchangeably with
.above
.
.least(n[, msg])
Asserts that the target is a number or a date greater than or equal to the given
number or date n
respectively. However, it’s often best to assert that the target is equal to
its expected value.
expect(2).to.equal(2); // Recommended
expect(2).to.be.at.least(1); // Not recommended
expect(2).to.be.at.least(2); // Not recommended
Add .lengthOf
earlier in the chain to assert that the target’s length
or size
is greater than or equal to the given number n
.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.have.lengthOf.at.least(2); // Not recommended
expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended
Add .not
earlier in the chain to negate .least
.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.at.least(2); // Not recommended
.least
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(1).to.be.at.least(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.at.least(2);
The aliases .gte
and .greaterThanOrEqual
can be used interchangeably with
.least
.
.below(n[, msg])
Asserts that the target is a number or a date less than the given number or date n
respectively.
However, it’s often best to assert that the target is equal to its expected
value.
expect(1).to.equal(1); // Recommended
expect(1).to.be.below(2); // Not recommended
Add .lengthOf
earlier in the chain to assert that the target’s length
or size
is less than the given number n
.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.have.lengthOf.below(4); // Not recommended
expect([1, 2, 3]).to.have.length(3); // Recommended
expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended
Add .not
earlier in the chain to negate .below
.
expect(2).to.equal(2); // Recommended
expect(2).to.not.be.below(1); // Not recommended
.below
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(2).to.be.below(1, 'nooo why fail??');
expect(2, 'nooo why fail??').to.be.below(1);
The aliases .lt
and .lessThan
can be used interchangeably with
.below
.
.most(n[, msg])
Asserts that the target is a number or a date less than or equal to the given number
or date n
respectively. However, it’s often best to assert that the target is equal to its
expected value.
expect(1).to.equal(1); // Recommended
expect(1).to.be.at.most(2); // Not recommended
expect(1).to.be.at.most(1); // Not recommended
Add .lengthOf
earlier in the chain to assert that the target’s length
or size
is less than or equal to the given number n
.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.have.lengthOf.at.most(4); // Not recommended
expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended
Add .not
earlier in the chain to negate .most
.
expect(2).to.equal(2); // Recommended
expect(2).to.not.be.at.most(1); // Not recommended
.most
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(2).to.be.at.most(1, 'nooo why fail??');
expect(2, 'nooo why fail??').to.be.at.most(1);
The aliases .lte
and .lessThanOrEqual
can be used interchangeably with
.most
.
.within(start, finish[, msg])
Asserts that the target is a number or a date greater than or equal to the given
number or date start
, and less than or equal to the given number or date finish
respectively.
However, it’s often best to assert that the target is equal to its expected
value.
expect(2).to.equal(2); // Recommended
expect(2).to.be.within(1, 3); // Not recommended
expect(2).to.be.within(2, 3); // Not recommended
expect(2).to.be.within(1, 2); // Not recommended
Add .lengthOf
earlier in the chain to assert that the target’s length
or size
is greater than or equal to the given number start
, and less
than or equal to the given number finish
.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
expect([1, 2, 3]).to.have.lengthOf(3); // Recommended
expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended
Add .not
earlier in the chain to negate .within
.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.within(2, 4); // Not recommended
.within
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect(4).to.be.within(1, 3, 'nooo why fail??');
expect(4, 'nooo why fail??').to.be.within(1, 3);
.instanceof(constructor[, msg])
Asserts that the target is an instance of the given constructor
.
function Cat () { }
expect(new Cat()).to.be.an.instanceof(Cat);
expect([1, 2]).to.be.an.instanceof(Array);
Add .not
earlier in the chain to negate .instanceof
.
expect({a: 1}).to.not.be.an.instanceof(Array);
.instanceof
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
Due to limitations in ES5, .instanceof
may not always work as expected
when using a transpiler such as Babel or TypeScript. In particular, it may
produce unexpected results when subclassing built-in object such as
Array
, Error
, and Map
. See your transpiler’s docs for details:
- (Babel)
- (TypeScript)
The alias .instanceOf
can be used interchangeably with .instanceof
.
.property(name[, val[, msg]])
Asserts that the target has a property with the given key name
.
expect({a: 1}).to.have.property('a');
When val
is provided, .property
also asserts that the property’s value
is equal to the given val
.
expect({a: 1}).to.have.property('a', 1);
By default, strict (===
) equality is used. Add .deep
earlier in the
chain to use deep equality instead. See the deep-eql
project page for
info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
// Target object deeply (but not strictly) has property `x: {a: 1}`
expect({x: {a: 1}}).to.have.deep.property('x', {a: 1});
expect({x: {a: 1}}).to.not.have.property('x', {a: 1});
The target’s enumerable and non-enumerable properties are always included
in the search. By default, both own and inherited properties are included.
Add .own
earlier in the chain to exclude inherited properties from the
search.
Object.prototype.b = 2;
expect({a: 1}).to.have.own.property('a');
expect({a: 1}).to.have.own.property('a', 1);
expect({a: 1}).to.have.property('b');
expect({a: 1}).to.not.have.own.property('b');
.deep
and .own
can be combined.
expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
Add .nested
earlier in the chain to enable dot- and bracket-notation when
referencing nested properties.
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y');
If .
or []
are part of an actual property name, they can be escaped by
adding two backslashes before them.
expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
.deep
and .nested
can be combined.
expect({a: {b: [{c: 3}]}})
.to.have.deep.nested.property('a.b[0]', {c: 3});
.own
and .nested
cannot be combined.
Add .not
earlier in the chain to negate .property
.
expect({a: 1}).to.not.have.property('b');
However, it’s dangerous to negate .property
when providing val
. The
problem is that it creates uncertain expectations by asserting that the
target either doesn’t have a property with the given key name
, or that it
does have a property with the given key name
but its value isn’t equal to
the given val
. It’s often best to identify the exact output that’s
expected, and then write an assertion that only accepts that exact output.
When the target isn’t expected to have a property with the given key
name
, it’s often best to assert exactly that.
expect({b: 2}).to.not.have.property('a'); // Recommended
expect({b: 2}).to.not.have.property('a', 1); // Not recommended
When the target is expected to have a property with the given key name
,
it’s often best to assert that the property has its expected value, rather
than asserting that it doesn’t have one of many unexpected values.
expect({a: 3}).to.have.property('a', 3); // Recommended
expect({a: 3}).to.not.have.property('a', 1); // Not recommended
.property
changes the target of any assertions that follow in the chain
to be the value of the property from the original target object.
expect({a: 1}).to.have.property('a').that.is.a('number');
.property
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
. When not providing val
, only use the
second form.
// Recommended
expect({a: 1}).to.have.property('a', 2, 'nooo why fail??');
expect({a: 1}, 'nooo why fail??').to.have.property('a', 2);
expect({a: 1}, 'nooo why fail??').to.have.property('b');
// Not recommended
expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
The above assertion isn’t the same thing as not providing val
. Instead,
it’s asserting that the target object has a b
property that’s equal to
undefined
.
The assertions .ownProperty
and .haveOwnProperty
can be used
interchangeably with .own.property
.
.ownPropertyDescriptor(name[, descriptor[, msg]])
Asserts that the target has its own property descriptor with the given key
name
. Enumerable and non-enumerable properties are included in the
search.
expect({a: 1}).to.have.ownPropertyDescriptor('a');
When descriptor
is provided, .ownPropertyDescriptor
also asserts that
the property’s descriptor is deeply equal to the given descriptor
. See
the deep-eql
project page for info on the deep equality algorithm:
https://github.com/chaijs/deep-eql.
expect({a: 1}).to.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 1,
});
Add .not
earlier in the chain to negate .ownPropertyDescriptor
.
expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
However, it’s dangerous to negate .ownPropertyDescriptor
when providing
a descriptor
. The problem is that it creates uncertain expectations by
asserting that the target either doesn’t have a property descriptor with
the given key name
, or that it does have a property descriptor with the
given key name
but it’s not deeply equal to the given descriptor
. It’s
often best to identify the exact output that’s expected, and then write an
assertion that only accepts that exact output.
When the target isn’t expected to have a property descriptor with the given
key name
, it’s often best to assert exactly that.
// Recommended
expect({b: 2}).to.not.have.ownPropertyDescriptor('a');
// Not recommended
expect({b: 2}).to.not.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 1,
});
When the target is expected to have a property descriptor with the given
key name
, it’s often best to assert that the property has its expected
descriptor, rather than asserting that it doesn’t have one of many
unexpected descriptors.
// Recommended
expect({a: 3}).to.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 3,
});
// Not recommended
expect({a: 3}).to.not.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 1,
});
.ownPropertyDescriptor
changes the target of any assertions that follow
in the chain to be the value of the property descriptor from the original
target object.
expect({a: 1}).to.have.ownPropertyDescriptor('a')
.that.has.property('enumerable', true);
.ownPropertyDescriptor
accepts an optional msg
argument which is a
custom error message to show when the assertion fails. The message can also
be given as the second argument to expect
. When not providing
descriptor
, only use the second form.
// Recommended
expect({a: 1}).to.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 2,
}, 'nooo why fail??');
// Recommended
expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 2,
});
// Recommended
expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
// Not recommended
expect({a: 1})
.to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??');
The above assertion isn’t the same thing as not providing descriptor
.
Instead, it’s asserting that the target object has a b
property
descriptor that’s deeply equal to undefined
.
The alias .haveOwnPropertyDescriptor
can be used interchangeably with
.ownPropertyDescriptor
.
.lengthOf(n[, msg])
Asserts that the target’s length
or size
is equal to the given number
n
.
expect([1, 2, 3]).to.have.lengthOf(3);
expect('foo').to.have.lengthOf(3);
expect(new Set([1, 2, 3])).to.have.lengthOf(3);
expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
Add .not
earlier in the chain to negate .lengthOf
. However, it’s often
best to assert that the target’s length
property is equal to its expected
value, rather than not equal to one of many unexpected values.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.not.have.lengthOf(4); // Not recommended
.lengthOf
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
.lengthOf
can also be used as a language chain, causing all .above
,
.below
, .least
, .most
, and .within
assertions that follow in the
chain to use the target’s length
property as the target. However, it’s
often best to assert that the target’s length
property is equal to its
expected length, rather than asserting that its length
property falls
within some range of values.
// Recommended
expect([1, 2, 3]).to.have.lengthOf(3);
// Not recommended
expect([1, 2, 3]).to.have.lengthOf.above(2);
expect([1, 2, 3]).to.have.lengthOf.below(4);
expect([1, 2, 3]).to.have.lengthOf.at.least(3);
expect([1, 2, 3]).to.have.lengthOf.at.most(3);
expect([1, 2, 3]).to.have.lengthOf.within(2,4);
Due to a compatibility issue, the alias .length
can’t be chained directly
off of an uninvoked method such as .a
. Therefore, .length
can’t be used
interchangeably with .lengthOf
in every situation. It’s recommended to
always use .lengthOf
instead of .length
.
expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error
expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected
.match(re[, msg])
Asserts that the target matches the given regular expression re
.
expect('foobar').to.match(/^foo/);
Add .not
earlier in the chain to negate .match
.
expect('foobar').to.not.match(/taco/);
.match
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect('foobar').to.match(/taco/, 'nooo why fail??');
expect('foobar', 'nooo why fail??').to.match(/taco/);
The alias .matches
can be used interchangeably with .match
.
.string(str[, msg])
Asserts that the target string contains the given substring str
.
expect('foobar').to.have.string('bar');
Add .not
earlier in the chain to negate .string
.
expect('foobar').to.not.have.string('taco');
.string
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect('foobar').to.have.string('taco', 'nooo why fail??');
expect('foobar', 'nooo why fail??').to.have.string('taco');
.keys(key1[, key2[, …]])
Asserts that the target object, array, map, or set has the given keys. Only the target’s own inherited properties are included in the search.
When the target is an object or array, keys can be provided as one or more string arguments, a single array argument, or a single object argument. In the latter case, only the keys in the given object matter; the values are ignored.
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
expect(['x', 'y']).to.have.all.keys(0, 1);
expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']);
expect(['x', 'y']).to.have.all.keys([0, 1]);
expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5
expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5
When the target is a map or set, each key must be provided as a separate argument.
expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
Because .keys
does different things based on the target’s type, it’s
important to check the target’s type before using .keys
. See the .a
doc
for info on testing a target’s type.
expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
By default, strict (===
) equality is used to compare keys of maps and
sets. Add .deep
earlier in the chain to use deep equality instead. See
the deep-eql
project page for info on the deep equality algorithm:
https://github.com/chaijs/deep-eql.
// Target set deeply (but not strictly) has key `{a: 1}`
expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]);
expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]);
By default, the target must have all of the given keys and no more. Add
.any
earlier in the chain to only require that the target have at least
one of the given keys. Also, add .not
earlier in the chain to negate
.keys
. It’s often best to add .any
when negating .keys
, and to use
.all
when asserting .keys
without negation.
When negating .keys
, .any
is preferred because .not.any.keys
asserts
exactly what’s expected of the output, whereas .not.all.keys
creates
uncertain expectations.
// Recommended; asserts that target doesn't have any of the given keys
expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
// Not recommended; asserts that target doesn't have all of the given
// keys but may or may not have some of them
expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd');
When asserting .keys
without negation, .all
is preferred because
.all.keys
asserts exactly what’s expected of the output, whereas
.any.keys
creates uncertain expectations.
// Recommended; asserts that target has all the given keys
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
// Not recommended; asserts that target has at least one of the given
// keys but may or may not have more of them
expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
Note that .all
is used by default when neither .all
nor .any
appear
earlier in the chain. However, it’s often best to add .all
anyway because
it improves readability.
// Both assertions are identical
expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended
expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended
Add .include
earlier in the chain to require that the target’s keys be a
superset of the expected keys, rather than identical sets.
// Target object's keys are a superset of ['a', 'b'] but not identical
expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b');
expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b');
However, if .any
and .include
are combined, only the .any
takes
effect. The .include
is ignored in this case.
// Both assertions are identical
expect({a: 1}).to.have.any.keys('a', 'b');
expect({a: 1}).to.include.any.keys('a', 'b');
A custom error message can be given as the second argument to expect
.
expect({a: 1}, 'nooo why fail??').to.have.key('b');
The alias .key
can be used interchangeably with .keys
.
.throw([errorLike], [errMsgMatcher], [msg])
When no arguments are provided, .throw
invokes the target function and
asserts that an error is thrown.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
When one argument is provided, and it’s an error constructor, .throw
invokes the target function and asserts that an error is thrown that’s an
instance of that error constructor.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(TypeError);
When one argument is provided, and it’s an error instance, .throw
invokes
the target function and asserts that an error is thrown that’s strictly
(===
) equal to that error instance.
var err = new TypeError('Illegal salmon!');
var badFn = function () { throw err; };
expect(badFn).to.throw(err);
When one argument is provided, and it’s a string, .throw
invokes the
target function and asserts that an error is thrown with a message that
contains that string.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw('salmon');
When one argument is provided, and it’s a regular expression, .throw
invokes the target function and asserts that an error is thrown with a
message that matches that regular expression.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(/salmon/);
When two arguments are provided, and the first is an error instance or
constructor, and the second is a string or regular expression, .throw
invokes the function and asserts that an error is thrown that fulfills both
conditions as described above.
var err = new TypeError('Illegal salmon!');
var badFn = function () { throw err; };
expect(badFn).to.throw(TypeError, 'salmon');
expect(badFn).to.throw(TypeError, /salmon/);
expect(badFn).to.throw(err, 'salmon');
expect(badFn).to.throw(err, /salmon/);
Add .not
earlier in the chain to negate .throw
.
var goodFn = function () {};
expect(goodFn).to.not.throw();
However, it’s dangerous to negate .throw
when providing any arguments.
The problem is that it creates uncertain expectations by asserting that the
target either doesn’t throw an error, or that it throws an error but of a
different type than the given type, or that it throws an error of the given
type but with a message that doesn’t include the given string. It’s often
best to identify the exact output that’s expected, and then write an
assertion that only accepts that exact output.
When the target isn’t expected to throw an error, it’s often best to assert exactly that.
var goodFn = function () {};
expect(goodFn).to.not.throw(); // Recommended
expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
When the target is expected to throw an error, it’s often best to assert that the error is of its expected type, and has a message that includes an expected string, rather than asserting that it doesn’t have one of many unexpected types, and doesn’t have a message that includes some string.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(TypeError, 'salmon'); // Recommended
expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended
.throw
changes the target of any assertions that follow in the chain to
be the error object that’s thrown.
var err = new TypeError('Illegal salmon!');
err.code = 42;
var badFn = function () { throw err; };
expect(badFn).to.throw(TypeError).with.property('code', 42);
.throw
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
. When not providing two arguments, always use
the second form.
var goodFn = function () {};
expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
expect(goodFn, 'nooo why fail??').to.throw();
Due to limitations in ES5, .throw
may not always work as expected when
using a transpiler such as Babel or TypeScript. In particular, it may
produce unexpected results when subclassing the built-in Error
object and
then passing the subclassed constructor to .throw
. See your transpiler’s
docs for details:
- (Babel)
- (TypeScript)
Beware of some common mistakes when using the throw
assertion. One common
mistake is to accidentally invoke the function yourself instead of letting
the throw
assertion invoke the function for you. For example, when
testing if a function named fn
throws, provide fn
instead of fn()
as
the target for the assertion.
expect(fn).to.throw(); // Good! Tests `fn` as desired
expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`
If you need to assert that your function fn
throws when passed certain
arguments, then wrap a call to fn
inside of another function.
expect(function () { fn(42); }).to.throw(); // Function expression
expect(() => fn(42)).to.throw(); // ES6 arrow function
Another common mistake is to provide an object method (or any stand-alone
function that relies on this
) as the target of the assertion. Doing so is
problematic because the this
context will be lost when the function is
invoked by .throw
; there’s no way for it to know what this
is supposed
to be. There are two ways around this problem. One solution is to wrap the
method or function call inside of another function. Another solution is to
use bind
.
expect(function () { cat.meow(); }).to.throw(); // Function expression
expect(() => cat.meow()).to.throw(); // ES6 arrow function
expect(cat.meow.bind(cat)).to.throw(); // Bind
Finally, it’s worth mentioning that it’s a best practice in JavaScript to
only throw Error
and derivatives of Error
such as ReferenceError
,
TypeError
, and user-defined objects that extend Error
. No other type of
value will generate a stack trace when initialized. With that said, the
throw
assertion does technically support any type of value being thrown,
not just Error
and its derivatives.
The aliases .throws
and .Throw
can be used interchangeably with
.throw
.
.respondTo(method[, msg])
When the target is a non-function object, .respondTo
asserts that the
target has a method with the given name method
. The method can be own or
inherited, and it can be enumerable or non-enumerable.
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.respondTo('meow');
When the target is a function, .respondTo
asserts that the target’s
prototype
property has a method with the given name method
. Again, the
method can be own or inherited, and it can be enumerable or non-enumerable.
function Cat () {}
Cat.prototype.meow = function () {};
expect(Cat).to.respondTo('meow');
Add .itself
earlier in the chain to force .respondTo
to treat the
target as a non-function object, even if it’s a function. Thus, it asserts
that the target has a method with the given name method
, rather than
asserting that the target’s prototype
property has a method with the
given name method
.
function Cat () {}
Cat.prototype.meow = function () {};
Cat.hiss = function () {};
expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
When not adding .itself
, it’s important to check the target’s type before
using .respondTo
. See the .a
doc for info on checking a target’s type.
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.be.an('object').that.respondsTo('meow');
Add .not
earlier in the chain to negate .respondTo
.
function Dog () {}
Dog.prototype.bark = function () {};
expect(new Dog()).to.not.respondTo('meow');
.respondTo
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect({}).to.respondTo('meow', 'nooo why fail??');
expect({}, 'nooo why fail??').to.respondTo('meow');
The alias .respondsTo
can be used interchangeably with .respondTo
.
.itself
Forces all .respondTo
assertions that follow in the chain to behave as if
the target is a non-function object, even if it’s a function. Thus, it
causes .respondTo
to assert that the target has a method with the given
name, rather than asserting that the target’s prototype
property has a
method with the given name.
function Cat () {}
Cat.prototype.meow = function () {};
Cat.hiss = function () {};
expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
.satisfy(matcher[, msg])
Invokes the given matcher
function with the target being passed as the
first argument, and asserts that the value returned is truthy.
expect(1).to.satisfy(function(num) {
return num > 0;
});
Add .not
earlier in the chain to negate .satisfy
.
expect(1).to.not.satisfy(function(num) {
return num > 2;
});
.satisfy
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect(1).to.satisfy(function(num) {
return num > 2;
}, 'nooo why fail??');
expect(1, 'nooo why fail??').to.satisfy(function(num) {
return num > 2;
});
The alias .satisfies
can be used interchangeably with .satisfy
.
.closeTo(expected, delta[, msg])
Asserts that the target is a number that’s within a given +/- delta
range
of the given number expected
. However, it’s often best to assert that the
target is equal to its expected value.
// Recommended
expect(1.5).to.equal(1.5);
// Not recommended
expect(1.5).to.be.closeTo(1, 0.5);
expect(1.5).to.be.closeTo(2, 0.5);
expect(1.5).to.be.closeTo(1, 1);
Add .not
earlier in the chain to negate .closeTo
.
expect(1.5).to.equal(1.5); // Recommended
expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
.closeTo
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
The alias .approximately
can be used interchangeably with .closeTo
.
.members(set[, msg])
Asserts that the target array has the same members as the given array
set
.
expect([1, 2, 3]).to.have.members([2, 1, 3]);
expect([1, 2, 2]).to.have.members([2, 1, 2]);
By default, members are compared using strict (===
) equality. Add .deep
earlier in the chain to use deep equality instead. See the deep-eql
project page for info on the deep equality algorithm:
https://github.com/chaijs/deep-eql.
// Target array deeply (but not strictly) has member `{a: 1}`
expect([{a: 1}]).to.have.deep.members([{a: 1}]);
expect([{a: 1}]).to.not.have.members([{a: 1}]);
By default, order doesn’t matter. Add .ordered
earlier in the chain to
require that members appear in the same order.
expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]);
expect([1, 2, 3]).to.have.members([2, 1, 3])
.but.not.ordered.members([2, 1, 3]);
By default, both arrays must be the same size. Add .include
earlier in
the chain to require that the target’s members be a superset of the
expected members. Note that duplicates are ignored in the subset when
.include
is added.
// Target array is a superset of [1, 2] but not identical
expect([1, 2, 3]).to.include.members([1, 2]);
expect([1, 2, 3]).to.not.have.members([1, 2]);
// Duplicates in the subset are ignored
expect([1, 2, 3]).to.include.members([1, 2, 2, 2]);
.deep
, .ordered
, and .include
can all be combined. However, if
.include
and .ordered
are combined, the ordering begins at the start of
both arrays.
expect([{a: 1}, {b: 2}, {c: 3}])
.to.include.deep.ordered.members([{a: 1}, {b: 2}])
.but.not.include.deep.ordered.members([{b: 2}, {c: 3}]);
Add .not
earlier in the chain to negate .members
. However, it’s
dangerous to do so. The problem is that it creates uncertain expectations
by asserting that the target array doesn’t have all of the same members as
the given array set
but may or may not have some of them. It’s often best
to identify the exact output that’s expected, and then write an assertion
that only accepts that exact output.
expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
.members
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
.
expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??');
expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]);
.oneOf(list[, msg])
Asserts that the target is a member of the given array list
. However,
it’s often best to assert that the target is equal to its expected value.
expect(1).to.equal(1); // Recommended
expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
Comparisons are performed using strict (===
) equality.
Add .not
earlier in the chain to negate .oneOf
.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
It can also be chained with .contain
or .include
, which will work with
both arrays and strings:
expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy'])
expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy'])
expect([1,2,3]).to.contain.oneOf([3,4,5])
expect([1,2,3]).to.not.contain.oneOf([4,5,6])
.oneOf
accepts an optional msg
argument which is a custom error message
to show when the assertion fails. The message can also be given as the
second argument to expect
.
expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]);
.change(subject[, prop[, msg]])
When one argument is provided, .change
asserts that the given function
subject
returns a different value when it’s invoked before the target
function compared to when it’s invoked afterward. However, it’s often best
to assert that subject
is equal to its expected value.
var dots = ''
, addDot = function () { dots += '.'; }
, getDots = function () { return dots; };
// Recommended
expect(getDots()).to.equal('');
addDot();
expect(getDots()).to.equal('.');
// Not recommended
expect(addDot).to.change(getDots);
When two arguments are provided, .change
asserts that the value of the
given object subject
’s prop
property is different before invoking the
target function compared to afterward.
var myObj = {dots: ''}
, addDot = function () { myObj.dots += '.'; };
// Recommended
expect(myObj).to.have.property('dots', '');
addDot();
expect(myObj).to.have.property('dots', '.');
// Not recommended
expect(addDot).to.change(myObj, 'dots');
Strict (===
) equality is used to compare before and after values.
Add .not
earlier in the chain to negate .change
.
var dots = ''
, noop = function () {}
, getDots = function () { return dots; };
expect(noop).to.not.change(getDots);
var myObj = {dots: ''}
, noop = function () {};
expect(noop).to.not.change(myObj, 'dots');
.change
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
. When not providing two arguments, always
use the second form.
var myObj = {dots: ''}
, addDot = function () { myObj.dots += '.'; };
expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??');
var dots = ''
, addDot = function () { dots += '.'; }
, getDots = function () { return dots; };
expect(addDot, 'nooo why fail??').to.not.change(getDots);
.change
also causes all .by
assertions that follow in the chain to
assert how much a numeric subject was increased or decreased by. However,
it’s dangerous to use .change.by
. The problem is that it creates
uncertain expectations by asserting that the subject either increases by
the given delta, or that it decreases by the given delta. It’s often best
to identify the exact output that’s expected, and then write an assertion
that only accepts that exact output.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; }
, subtractTwo = function () { myObj.val -= 2; };
expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
The alias .changes
can be used interchangeably with .change
.
.increase(subject[, prop[, msg]])
When one argument is provided, .increase
asserts that the given function
subject
returns a greater number when it’s invoked after invoking the
target function compared to when it’s invoked beforehand. .increase
also
causes all .by
assertions that follow in the chain to assert how much
greater of a number is returned. It’s often best to assert that the return
value increased by the expected amount, rather than asserting it increased
by any amount.
var val = 1
, addTwo = function () { val += 2; }
, getVal = function () { return val; };
expect(addTwo).to.increase(getVal).by(2); // Recommended
expect(addTwo).to.increase(getVal); // Not recommended
When two arguments are provided, .increase
asserts that the value of the
given object subject
’s prop
property is greater after invoking the
target function compared to beforehand.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
expect(addTwo).to.increase(myObj, 'val'); // Not recommended
Add .not
earlier in the chain to negate .increase
. However, it’s
dangerous to do so. The problem is that it creates uncertain expectations
by asserting that the subject either decreases, or that it stays the same.
It’s often best to identify the exact output that’s expected, and then
write an assertion that only accepts that exact output.
When the subject is expected to decrease, it’s often best to assert that it decreased by the expected amount.
var myObj = {val: 1}
, subtractTwo = function () { myObj.val -= 2; };
expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
When the subject is expected to stay the same, it’s often best to assert exactly that.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.not.change(myObj, 'val'); // Recommended
expect(noop).to.not.increase(myObj, 'val'); // Not recommended
.increase
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
. When not providing two arguments, always
use the second form.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.increase(myObj, 'val', 'nooo why fail??');
var val = 1
, noop = function () {}
, getVal = function () { return val; };
expect(noop, 'nooo why fail??').to.increase(getVal);
The alias .increases
can be used interchangeably with .increase
.
.decrease(subject[, prop[, msg]])
When one argument is provided, .decrease
asserts that the given function
subject
returns a lesser number when it’s invoked after invoking the
target function compared to when it’s invoked beforehand. .decrease
also
causes all .by
assertions that follow in the chain to assert how much
lesser of a number is returned. It’s often best to assert that the return
value decreased by the expected amount, rather than asserting it decreased
by any amount.
var val = 1
, subtractTwo = function () { val -= 2; }
, getVal = function () { return val; };
expect(subtractTwo).to.decrease(getVal).by(2); // Recommended
expect(subtractTwo).to.decrease(getVal); // Not recommended
When two arguments are provided, .decrease
asserts that the value of the
given object subject
’s prop
property is lesser after invoking the
target function compared to beforehand.
var myObj = {val: 1}
, subtractTwo = function () { myObj.val -= 2; };
expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended
Add .not
earlier in the chain to negate .decrease
. However, it’s
dangerous to do so. The problem is that it creates uncertain expectations
by asserting that the subject either increases, or that it stays the same.
It’s often best to identify the exact output that’s expected, and then
write an assertion that only accepts that exact output.
When the subject is expected to increase, it’s often best to assert that it increased by the expected amount.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
When the subject is expected to stay the same, it’s often best to assert exactly that.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.not.change(myObj, 'val'); // Recommended
expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
.decrease
accepts an optional msg
argument which is a custom error
message to show when the assertion fails. The message can also be given as
the second argument to expect
. When not providing two arguments, always
use the second form.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.decrease(myObj, 'val', 'nooo why fail??');
var val = 1
, noop = function () {}
, getVal = function () { return val; };
expect(noop, 'nooo why fail??').to.decrease(getVal);
The alias .decreases
can be used interchangeably with .decrease
.
.by(delta[, msg])
When following an .increase
assertion in the chain, .by
asserts that
the subject of the .increase
assertion increased by the given delta
.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(2);
When following a .decrease
assertion in the chain, .by
asserts that the
subject of the .decrease
assertion decreased by the given delta
.
var myObj = {val: 1}
, subtractTwo = function () { myObj.val -= 2; };
expect(subtractTwo).to.decrease(myObj, 'val').by(2);
When following a .change
assertion in the chain, .by
asserts that the
subject of the .change
assertion either increased or decreased by the
given delta
. However, it’s dangerous to use .change.by
. The problem is
that it creates uncertain expectations. It’s often best to identify the
exact output that’s expected, and then write an assertion that only accepts
that exact output.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; }
, subtractTwo = function () { myObj.val -= 2; };
expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended
expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended
Add .not
earlier in the chain to negate .by
. However, it’s often best
to assert that the subject changed by its expected delta, rather than
asserting that it didn’t change by one of countless unexpected deltas.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
// Recommended
expect(addTwo).to.increase(myObj, 'val').by(2);
// Not recommended
expect(addTwo).to.increase(myObj, 'val').but.not.by(3);
.by
accepts an optional msg
argument which is a custom error message to
show when the assertion fails. The message can also be given as the second
argument to expect
.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??');
expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3);
.extensible
Asserts that the target is extensible, which means that new properties can be added to it. Primitives are never extensible.
expect({a: 1}).to.be.extensible;
Add .not
earlier in the chain to negate .extensible
.
var nonExtensibleObject = Object.preventExtensions({})
, sealedObject = Object.seal({})
, frozenObject = Object.freeze({});
expect(nonExtensibleObject).to.not.be.extensible;
expect(sealedObject).to.not.be.extensible;
expect(frozenObject).to.not.be.extensible;
expect(1).to.not.be.extensible;
A custom error message can be given as the second argument to expect
.
expect(1, 'nooo why fail??').to.be.extensible;
.sealed
Asserts that the target is sealed, which means that new properties can’t be added to it, and its existing properties can’t be reconfigured or deleted. However, it’s possible that its existing properties can still be reassigned to different values. Primitives are always sealed.
var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});
expect(sealedObject).to.be.sealed;
expect(frozenObject).to.be.sealed;
expect(1).to.be.sealed;
Add .not
earlier in the chain to negate .sealed
.
expect({a: 1}).to.not.be.sealed;
A custom error message can be given as the second argument to expect
.
expect({a: 1}, 'nooo why fail??').to.be.sealed;
.frozen
Asserts that the target is frozen, which means that new properties can’t be added to it, and its existing properties can’t be reassigned to different values, reconfigured, or deleted. Primitives are always frozen.
var frozenObject = Object.freeze({});
expect(frozenObject).to.be.frozen;
expect(1).to.be.frozen;
Add .not
earlier in the chain to negate .frozen
.
expect({a: 1}).to.not.be.frozen;
A custom error message can be given as the second argument to expect
.
expect({a: 1}, 'nooo why fail??').to.be.frozen;
.finite
Asserts that the target is a number, and isn’t NaN
or positive/negative
Infinity
.
expect(1).to.be.finite;
Add .not
earlier in the chain to negate .finite
. However, it’s
dangerous to do so. The problem is that it creates uncertain expectations
by asserting that the subject either isn’t a number, or that it’s NaN
, or
that it’s positive Infinity
, or that it’s negative Infinity
. It’s often
best to identify the exact output that’s expected, and then write an
assertion that only accepts that exact output.
When the target isn’t expected to be a number, it’s often best to assert that it’s the expected type, rather than asserting that it isn’t one of many unexpected types.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.finite; // Not recommended
When the target is expected to be NaN
, it’s often best to assert exactly
that.
expect(NaN).to.be.NaN; // Recommended
expect(NaN).to.not.be.finite; // Not recommended
When the target is expected to be positive infinity, it’s often best to assert exactly that.
expect(Infinity).to.equal(Infinity); // Recommended
expect(Infinity).to.not.be.finite; // Not recommended
When the target is expected to be negative infinity, it’s often best to assert exactly that.
expect(-Infinity).to.equal(-Infinity); // Recommended
expect(-Infinity).to.not.be.finite; // Not recommended
A custom error message can be given as the second argument to expect
.
expect('foo', 'nooo why fail??').to.be.finite;
.fail([message])
.fail(actual, expected, [message], [operator])
Throw a failure.
expect.fail();
expect.fail("custom error message");
expect.fail(1, 2);
expect.fail(1, 2, "custom error message");
expect.fail(1, 2, "custom error message", ">");
expect.fail(1, 2, undefined, ">");
.fail([message])
.fail(actual, expected, [message], [operator])
Throw a failure.
should.fail();
should.fail("custom error message");
should.fail(1, 2);
should.fail(1, 2, "custom error message");
should.fail(1, 2, "custom error message", ">");
should.fail(1, 2, undefined, ">");