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.
The following are provided as chainable getters to improve the readability of your assertions. They do not provide testing capabilities unless they have been overwritten by a plugin.
Chains
Negates any of assertions following in the chain.
expect(foo).to.not.equal('bar');
expect(goodFn).to.not.throw(Error);
expect({ foo: 'baz' }).to.have.property('foo')
.and.not.equal('bar');
Sets the deep
flag, later used by the equal
and property
assertions.
expect(foo).to.deep.equal({ bar: 'baz' });
expect({ foo: { bar: { baz: 'quux' } } })
.to.have.deep.property('foo.bar.baz', 'quux');
.deep.property
special characters can be escaped by adding two slashes before the .
or []
.
var deepCss = { '.link': { '[target]': 42 }};
expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
Sets the any
flag, (opposite of the all
flag) later used in the keys
assertion.
expect(foo).to.have.any.keys('bar', 'baz');
Sets the all
flag (opposite of the any
flag) later used by the keys
assertion.
expect(foo).to.have.all.keys('bar', 'baz');
The a
and an
assertions are aliases that can be used either as language chains or to assert a value’s type.
// typeof
expect('test').to.be.a('string');
expect({ foo: 'bar' }).to.be.an('object');
expect(null).to.be.a('null');
expect(undefined).to.be.an('undefined');
expect(new Error).to.be.an('error');
expect(new Promise).to.be.a('promise');
expect(new Float32Array()).to.be.a('float32array');
expect(Symbol()).to.be.a('symbol');
// es6 overrides
expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');
// language chain
expect(foo).to.be.an.instanceof(Foo);
The include
and contain
assertions can be used as either property based language chains or as methods to assert the inclusion of an object in an array or a substring in a string. When used as language chains, they toggle the contains
flag for the keys
assertion.
expect([1,2,3]).to.include(2);
expect('foobar').to.contain('foo');
expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
Asserts that the target is truthy.
expect('everything').to.be.ok;
expect(1).to.be.ok;
expect(false).to.not.be.ok;
expect(undefined).to.not.be.ok;
expect(null).to.not.be.ok;
Asserts that the target is true
.
expect(true).to.be.true;
expect(1).to.not.be.true;
Asserts that the target is false
.
expect(false).to.be.false;
expect(0).to.not.be.false;
Asserts that the target is null
.
expect(null).to.be.null;
expect(undefined).to.not.be.null;
Asserts that the target is undefined
.
expect(undefined).to.be.undefined;
expect(null).to.not.be.undefined;
Asserts that the target is NaN
.
expect('foo').to.be.NaN;
expect(4).not.to.be.NaN;
Asserts that the target is neither null
nor undefined
.
var foo = 'hi'
, bar = null
, baz;
expect(foo).to.exist;
expect(bar).to.not.exist;
expect(baz).to.not.exist;
Asserts that the target’s length is 0
. For arrays and strings, it checks the length
property. For objects, it gets the count of enumerable keys.
expect([]).to.be.empty;
expect('').to.be.empty;
expect({}).to.be.empty;
Asserts that the target is an arguments object.
function test () {
expect(arguments).to.be.arguments;
}
Asserts that the target is strictly equal (===
) to value
. Alternately, if the deep
flag is set, asserts that the target is deeply equal to value
.
expect('hello').to.equal('hello');
expect(42).to.equal(42);
expect(1).to.not.equal(true);
expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
Asserts that the target is deeply equal to value
.
expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
Asserts that the target is greater than value
.
expect(10).to.be.above(5);
Can also be used in conjunction with length
to assert a minimum length. The benefit being a more informative error message than if the length was supplied directly.
expect('foo').to.have.length.above(2);
expect([ 1, 2, 3 ]).to.have.length.above(2);
Asserts that the target is greater than or equal to value
.
expect(10).to.be.at.least(10);
Can also be used in conjunction with length
to assert a minimum length. The benefit being a more informative error message than if the length was supplied directly.
expect('foo').to.have.length.of.at.least(2);
expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
Asserts that the target is less than value
.
expect(5).to.be.below(10);
Can also be used in conjunction with length
to assert a maximum length. The benefit being a more informative error message than if the length was supplied directly.
expect('foo').to.have.length.below(4);
expect([ 1, 2, 3 ]).to.have.length.below(4);
Asserts that the target is less than or equal to value
.
expect(5).to.be.at.most(5);
Can also be used in conjunction with length
to assert a maximum length. The benefit being a more informative error message than if the length was supplied directly.
expect('foo').to.have.length.of.at.most(4);
expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
Asserts that the target is within a range.
expect(7).to.be.within(5,10);
Can also be used in conjunction with length
to assert a length range. The benefit being a more informative error message than if the length was supplied directly.
expect('foo').to.have.length.within(2,4);
expect([ 1, 2, 3 ]).to.have.length.within(2,4);
Asserts that the target is an instance of constructor
.
var Tea = function (name) { this.name = name; }
, Chai = new Tea('chai');
expect(Chai).to.be.an.instanceof(Tea);
expect([ 1, 2, 3 ]).to.be.instanceof(Array);
Asserts that the target has a property name
, optionally asserting that the value of that property is strictly equal to value
. If the deep
flag is set, you can use dot- and bracket-notation for deep references into objects and arrays.
// simple referencing
var obj = { foo: 'bar' };
expect(obj).to.have.property('foo');
expect(obj).to.have.property('foo', 'bar');
// deep referencing
var deepObj = {
green: { tea: 'matcha' }
, teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
};
expect(deepObj).to.have.deep.property('green.tea', 'matcha');
expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
You can also use an array as the starting point of a deep.property
assertion, or traverse nested arrays.
var arr = [
[ 'chai', 'matcha', 'konacha' ]
, [ { tea: 'chai' }
, { tea: 'matcha' }
, { tea: 'konacha' } ]
];
expect(arr).to.have.deep.property('[0][1]', 'matcha');
expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
Furthermore, property
changes the subject of the assertion to be the value of that property from the original object. This permits for further chainable assertions on that property.
expect(obj).to.have.property('foo')
.that.is.a('string');
expect(deepObj).to.have.property('green')
.that.is.an('object')
.that.deep.equals({ tea: 'matcha' });
expect(deepObj).to.have.property('teas')
.that.is.an('array')
.with.deep.property('[2]')
.that.deep.equals({ tea: 'konacha' });
Note that dots and bracket in name
must be backslash-escaped when the deep
flag is set, while they must NOT be escaped when the deep
flag is not set.
// simple referencing
var css = { '.link[target]': 42 };
expect(css).to.have.property('.link[target]', 42);
// deep referencing
var deepCss = { '.link': { '[target]': 42 }};
expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42);
Asserts that the target has an own property name
.
expect('test').to.have.ownProperty('length');
Asserts that the target has an own property descriptor name
, that optionally matches descriptor
.
expect('test').to.have.ownPropertyDescriptor('length');
expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });
expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });
expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);
expect('test').ownPropertyDescriptor('length').to.have.keys('value');
Sets the doLength
flag later used as a chain precursor to a value comparison for the length
property.
expect('foo').to.have.length.above(2);
expect([ 1, 2, 3 ]).to.have.length.above(2);
expect('foo').to.have.length.below(4);
expect([ 1, 2, 3 ]).to.have.length.below(4);
expect('foo').to.have.length.within(2,4);
expect([ 1, 2, 3 ]).to.have.length.within(2,4);
Deprecation notice: Using length
as an assertion will be deprecated in version 2.4.0 and removed in 3.0.0. Code using the old style of asserting for length
property value using length(value)
should be switched to use lengthOf(value)
instead.
Asserts that the target’s length
property has the expected value.
expect([ 1, 2, 3]).to.have.lengthOf(3);
expect('foobar').to.have.lengthOf(6);
Asserts that the target matches a regular expression.
expect('foobar').to.match(/^foo/);
Asserts that the string target contains another string.
expect('foobar').to.have.string('bar');
Asserts that the target contains any or all of the passed-in keys. Use in combination with any
, all
, contains
, or have
will affect what will pass.
When used in conjunction with any
, at least one key that is passed in must exist in the target object. This is regardless whether or not the have
or contain
qualifiers are used. Note, either any
or all
should be used in the assertion. If neither are used, the assertion is defaulted to all
.
When both all
and contain
are used, the target object must have at least all of the passed-in keys but may have more keys not listed.
When both all
and have
are used, the target object must both contain all of the passed-in keys AND the number of keys in the target object must match the number of keys passed in (in other words, a target object must have all and only all of the passed-in keys).
expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');
expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');
expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');
expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);
expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});
expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);
expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);
expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});
Asserts that the function target will throw a specific error, or specific type of error (as determined using instanceof
), optionally with a RegExp or string inclusion test for the error’s message.
var err = new ReferenceError('This is a bad function.');
var fn = function () { throw err; }
expect(fn).to.throw(ReferenceError);
expect(fn).to.throw(Error);
expect(fn).to.throw(/bad function/);
expect(fn).to.not.throw('good function');
expect(fn).to.throw(ReferenceError, /bad function/);
expect(fn).to.throw(err);
Please note that when a throw expectation is negated, it will check each parameter independently, starting with error constructor type. The appropriate way to check for the existence of a type of error but for a message that does not match is to use and
.
expect(fn).to.throw(ReferenceError)
.and.not.throw(/good function/);
Asserts that the object or class target will respond to a method.
Klass.prototype.bar = function(){};
expect(Klass).to.respondTo('bar');
expect(obj).to.respondTo('bar');
To check if a constructor will respond to a static function, set the itself
flag.
Klass.baz = function(){};
expect(Klass).itself.to.respondTo('baz');
Sets the itself
flag, later used by the respondTo
assertion.
function Foo() {}
Foo.bar = function() {}
Foo.prototype.baz = function() {}
expect(Foo).itself.to.respondTo('bar');
expect(Foo).itself.not.to.respondTo('baz');
Asserts that the target passes a given truth test.
expect(1).to.satisfy(function(num) { return num > 0; });
Asserts that the target is equal expected
, to within a +/- delta
range.
expect(1.5).to.be.closeTo(1, 0.5);
Asserts that the target is a superset of set
, or that the target and set
have the same strictly-equal (===) members. Alternately, if the deep
flag is set, set members are compared for deep equality.
expect([1, 2, 3]).to.include.members([3, 2]);
expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
expect([4, 2]).to.have.members([2, 4]);
expect([5, 2]).to.not.have.members([5, 2, 1]);
expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);
Assert that a value appears somewhere in the top level of array list
.
expect('a').to.be.oneOf(['a', 'b', 'c']);
expect(9).to.not.be.oneOf(['z']);
expect([3]).to.not.be.oneOf([1, 2, [3]]);
var three = [3];
// for object-types, contents are not compared
expect(three).to.not.be.oneOf([1, 2, [3]]);
// comparing references works
expect(three).to.be.oneOf([1, 2, three]);
Asserts that a function changes an object property
var obj = { val: 10 };
var fn = function() { obj.val += 3 };
var noChangeFn = function() { return 'foo' + 'bar'; }
expect(fn).to.change(obj, 'val');
expect(noChangeFn).to.not.change(obj, 'val')
Asserts that a function increases an object property
var obj = { val: 10 };
var fn = function() { obj.val = 15 };
expect(fn).to.increase(obj, 'val');
Asserts that a function decreases an object property
var obj = { val: 10 };
var fn = function() { obj.val = 5 };
expect(fn).to.decrease(obj, 'val');
Asserts that the target is extensible (can have new properties added to it).
var nonExtensibleObject = Object.preventExtensions({});
var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});
expect({}).to.be.extensible;
expect(nonExtensibleObject).to.not.be.extensible;
expect(sealedObject).to.not.be.extensible;
expect(frozenObject).to.not.be.extensible;
Asserts that the target is sealed (cannot have new properties added to it and its existing properties cannot be removed).
var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});
expect(sealedObject).to.be.sealed;
expect(frozenObject).to.be.sealed;
expect({}).to.not.be.sealed;
Asserts that the target is frozen (cannot have new properties added to it and its existing properties cannot be modified).
var frozenObject = Object.freeze({});
expect(frozenObject).to.be.frozen;
expect({}).to.not.be.frozen;
© 2011–2015 Jake Luer
Licensed under the MIT License.
http://chaijs.com/api/bdd/