BDD
Стили BDD — expect и should. Оба используют одинаковый цепочечный язык для построения утверждений, но различаются способом начального построения утверждения. Обратитесь к Руководству по стилям для сравнения.
Ссылка на API
Цепочки языка
Ниже приведены цепочечные методы-геттеры для повышения читабельности ваших утверждений.
Цепочки
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
- still
- also
.not
Отменяет все последующие утверждения в цепочке.
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);
Просто потому, что вы можете отменить любое утверждение с помощью .not, не означает, что нужно это делать. С великой силой приходит большая ответственность. Чаще всего лучше утверждать, что был получен ожидаемый результат, а не утверждать, что не был получен один из бесчисленных неожиданных результатов. Обратитесь к отдельным утверждениям для получения конкретных рекомендаций.
expect(2).to.equal(2); // Recommended
expect(2).to.not.equal(1); // Not recommended
.deep
Приводит все .equal, .include, .members, .keys, и .property утверждения, следующие в цепочке, к использованию глубокого равенства вместо строгого (===) равенства. См. страницу проекта deep-eql для получения информации об алгоритме глубокого равенства: 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
Включает использование точечной и квадратной нотации во всех .property и .include утверждениях, следующих в цепочке.
expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]');
expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
Если . или [] являются частью фактического имени свойства, их можно экранировать, добавив две обратные косые черты перед ними.
expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'});
.nested не может быть объединен с .own.
.own
Приводит все .property и .include утверждения, следующие в цепочке, к игнорированию унаследованных свойств.
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 не может быть объединен с .nested.
.ordered
Приводит все .members утверждения, следующие в цепочке, к требованию, чтобы члены находились в том же порядке.
expect([1, 2]).to.have.ordered.members([1, 2])
.but.not.have.ordered.members([2, 1]);
Когда .include и .ordered объединены, упорядочение начинается с начала обоих массивов.
expect([1, 2, 3]).to.include.ordered.members([1, 2])
.but.not.include.ordered.members([2, 3]);
.any
Приводит все .keys утверждения, следующие в цепочке, к тому, чтобы требовать, чтобы целевой объект имел хотя бы один из заданных ключей. Это противоположно .all, которое требует, чтобы целевой объект имел все заданные ключи.
expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
См. документ .keys для получения рекомендаций по использованию .any или .all.
.all
Приводит все .keys утверждения, следующие в цепочке, к требованию, чтобы целевой объект имел все заданные ключи. Это противоположно .any, которое требует, чтобы целевой объект имел хотя бы один из заданных ключей.
expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
Обратите внимание, что .all используется по умолчанию, когда ни .all ни .any не добавлены ранее в цепочке. Однако часто лучше добавить .all, так как это повышает читаемость.
См. документ .keys для получения рекомендаций по использованию .any или .all.
.a(type[, msg])
Утверждает, что тип целевого объекта равен заданной строке type. Типы нечувствительны к регистру. См. страницу проекта type-detect для получения информации об алгоритме определения типа: 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 поддерживает объекты, у которых есть пользовательский тип, установленный с помощью Symbol.toStringTag.
var myObj = {
[Symbol.toStringTag]: 'myCustomType'
};
expect(myObj).to.be.a('myCustomType').but.not.an('object');
Чаще всего лучше использовать .a для проверки типа целевого объекта перед выполнением дополнительных утверждений для того же целевого объекта. Таким образом, вы избегаете неожиданного поведения любых утверждений, которые делают разные вещи в зависимости от типа целевого объекта.
expect([1, 2, 3]).to.be.an('array').that.includes(2);
expect([]).to.be.an('array').that.is.empty;
Добавьте .not ранее в цепочку, чтобы отменить .a. Однако часто лучше утверждать, что целевой объект является ожидаемым типом, а не утверждать, что он не является одним из многих неожиданных типов.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.an('array'); // Not recommended
.a принимает необязательный аргумент msg, который представляет собой пользовательское сообщение об ошибке, отображаемое при ошибке утверждения. Сообщение также может быть передано как второй аргумент в expect.
expect(1).to.be.a('string', 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.a('string');
.a также может использоваться как цепочка языка для повышения читаемости ваших утверждений.
expect({b: 2}).to.have.a.property('b');
Псевдоним .an может использоваться взаимозаменяемо с .a.
.include(val[, msg])
Когда целевое значение является строкой, .include проверяет, что заданная строка val является подстрокой целевого значения.
expect('foobar').to.include('foo');
Когда целевое значение является массивом, .include проверяет, что заданное значение val является элементом целевого массива.
expect([1, 2, 3]).to.include(2);
Когда целевое значение является объектом, .include проверяет, что свойства заданного объекта val являются подмножеством свойств целевого объекта.
expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
Когда целевое значение является набором (Set) или слабым набором (WeakSet), .include проверяет, что заданное значение val является элементом целевого набора. Используется алгоритм равенства SameValueZero.
expect(new Set([1, 2])).to.include(2);
Когда целевое значение является картой (Map), .include проверяет, что заданное значение val является одним из значений целевой карты. Используется алгоритм равенства SameValueZero.
expect(new Map([['a', 1], ['b', 2]])).to.include(2);
Так как .include ведет себя по-разному в зависимости от типа целевого значения, важно проверить тип целевого значения перед использованием .include. См. документацию .a для получения информации о проверке типа целевого значения.
expect([1, 2, 3]).to.be.an('array').that.includes(2);
По умолчанию для сравнения элементов массивов и свойств объектов используется строгое (===) равенство. Для использования глубокого равенства (для WeakSet целевые значения не поддерживаются) добавьте .deep ранее в цепочке. См. страницу проекта deep-eql для получения информации об алгоритме глубокого равенства: 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}});
По умолчанию при работе с объектами ищут все свойства целевого объекта, включая унаследованные и/или неперечисляемые. Для исключения унаследованных свойств целевого объекта из поиска добавьте .own ранее в цепочке.
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});
Обратите внимание, что целевой объект всегда ищут только среди собственных перечисляемых свойств объекта val.
.deep и .own могут быть объединены.
expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}});
Для включения использования точечной и квадратной нотации при ссылке на вложенные свойства добавьте .nested ранее в цепочке.
expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'});
Если . или [] являются частью фактического имени свойства, их можно экранировать, добавив перед ними два обратных слэша.
expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2});
.deep и .nested могут быть объединены.
expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}});
.own и .nested нельзя объединять.
Добавьте .not ранее в цепочке для инвертирования .include.
expect('foobar').to.not.include('taco');
expect([1, 2, 3]).to.not.include(4);
Однако инвертирование .include для целевого объекта опасно. Проблема в том, что это создает неопределённые ожидания, утверждая, что целевой объект не содержит все пары ключ/значение val, но может или не может содержать некоторые из них. Часто лучше определить точный ожидаемый результат и написать утверждение, которое принимает только этот точный результат.
Если от целевого объекта не ожидается наличие ключей val, часто лучше утверждать об этом напрямую.
expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended
expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended
Если от целевого объекта ожидаются ключи val, часто лучше утверждать, что каждое свойство имеет ожидаемое значение, а не утверждать, что каждое свойство не имеет одного из многих неожиданных значений.
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 принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также может быть передано в качестве второго аргумента для expect.
expect([1, 2, 3]).to.include(4, 'nooo why fail??');
expect([1, 2, 3], 'nooo why fail??').to.include(4);
.include также может использоваться как часть цепочки, заставляя все последующие утверждения .members и .keys требовать, чтобы целевое значение было супермножеством ожидаемого набора, а не идентичным набором. Обратите внимание, что .members игнорирует дубликаты в подмножестве, когда добавляется .include.
// 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]);
Обратите внимание, что добавление .any ранее в цепочке приводит к тому, что утверждение .keys игнорирует .include.
// Both assertions are identical
expect({a: 1}).to.include.any.keys('a', 'b');
expect({a: 1}).to.have.any.keys('a', 'b');
Псевдонимы .includes, .contain, и .contains могут быть использованы взаимозаменяемо с .include.
.ok
Проверяет, что целевое значение является истинным (считается true в контексте boolean). Однако часто лучше утверждать, что целевое значение строго (===) или глубоко равно своему ожидаемому значению.
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
Добавьте .not ранее в цепочке для инвертирования .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
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(false, 'nooo why fail??').to.be.ok;
.true
Проверяет, что целевое значение строго (===) равно true.
expect(true).to.be.true;
Добавьте .not ранее в цепочке для инвертирования .true. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению, а не не равно 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
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(false, 'nooo why fail??').to.be.true;
.false
Проверяет, что целевое значение строго (===) равно false.
expect(false).to.be.false;
Добавьте .not ранее в цепочке для инвертирования .false. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению, а не не равно 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
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(true, 'nooo why fail??').to.be.false;
.null
Проверяет, что целевое значение строго (===) равно null.
expect(null).to.be.null;
Добавьте .not ранее в цепочке для инвертирования .null. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению, а не не равно null.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.null; // Not recommended
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(42, 'nooo why fail??').to.be.null;
.undefined
Проверяет, что целевое значение строго (===) равно undefined.
expect(undefined).to.be.undefined;
Добавьте .not ранее в цепочке для инвертирования .undefined. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению, а не не равно undefined.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.undefined; // Not recommended
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(42, 'nooo why fail??').to.be.undefined;
.NaN
Проверяет, что целевое значение точно NaN.
expect(NaN).to.be.NaN;
Добавьте .not ранее в цепочке для инвертирования .NaN. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению, а не не равно NaN.
expect('foo').to.equal('foo'); // Recommended
expect('foo').to.not.be.NaN; // Not recommended
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(42, 'nooo why fail??').to.be.NaN;
.exist
Проверяет, что целевое значение не строго (===) равно ни null, ни undefined. Однако часто лучше утверждать, что целевое значение равно ожидаемому значению.
expect(1).to.equal(1); // Recommended
expect(1).to.exist; // Not recommended
expect(0).to.equal(0); // Recommended
expect(0).to.exist; // Not recommended
Добавьте .not ранее в цепочке для инвертирования .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
Пользовательское сообщение об ошибке можно передать в качестве второго аргумента к expect.
expect(null, 'nooo why fail??').to.exist;
Псевдоним .exists можно использовать взаимозаменяемо с .exist.
.empty
Когда целевой объект — строка или массив, .empty проверяет, что свойство целевого объекта length строго (===) равно 0.
expect([]).to.be.empty;
expect('').to.be.empty;
Когда целевой объект — карта или множество, .empty проверяет, что свойство целевого объекта size строго равно 0.
expect(new Set()).to.be.empty;
expect(new Map()).to.be.empty;
Когда целевой объект — обычный объект (не функция), .empty проверяет, что у целевого объекта нет перечисляемых собственных свойств. Свойства с ключами на основе символов не учитываются.
expect({}).to.be.empty;
Так как .empty ведет себя по-разному в зависимости от типа целевого объекта, важно проверить тип целевого объекта перед использованием .empty. См. документацию по .a для получения информации о проверке типа целевого объекта.
expect([]).to.be.an('array').that.is.empty;
Добавьте .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
Пользовательское сообщение об ошибке можно указать как второй аргумент к expect.
expect([1, 2, 3], 'nooo why fail??').to.be.empty;
.arguments
Проверяет, что целевой объект является объектом arguments.
function test () {
expect(arguments).to.be.arguments;
}
test();
Добавьте .not ранее в цепочке, чтобы инвертировать .arguments. Однако, часто лучше проверить ожидаемый тип целевого объекта, а не утверждать, что он не является объектом arguments.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.arguments; // Not recommended
Псевдоним .Arguments можно использовать взаимозаменяемо с .arguments.
.equal(val[, msg])
Проверяет, что целевой объект строго (===) равен заданному val.
expect(1).to.equal(1);
expect('foo').to.equal('foo');
Добавьте .deep ранее в цепочке, чтобы использовать глубокое сравнение. См. страницу проекта deep-eql для информации об алгоритме глубокого сравнения: 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]);
Добавьте .not ранее в цепочке, чтобы инвертировать .equal. Однако, часто лучше проверить, что целевой объект равен ожидаемому значению, а не не равен одному из бесчисленных неожиданных значений.
expect(1).to.equal(1); // Recommended
expect(1).to.not.equal(2); // Not recommended
.equal принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачной проверке. Сообщение также можно указать как второй аргумент к expect.
expect(1).to.equal(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.equal(2);
Псевдонимы .equals и eq можно использовать взаимозаменяемо с .equal.
.eql(obj[, msg])
Проверяет, что целевой объект глубоко равен заданному obj. См. страницу проекта deep-eql для информации об алгоритме глубокого сравнения: 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]);
Добавьте .not ранее в цепочке, чтобы инвертировать .eql. Однако, часто лучше проверить, что целевой объект глубоко равен ожидаемому значению, а не не глубоко равен одному из бесчисленных неожиданных значений.
expect({a: 1}).to.eql({a: 1}); // Recommended
expect({a: 1}).to.not.eql({b: 2}); // Not recommended
.eql принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачной проверке. Сообщение также можно указать как второй аргумент к expect.
expect({a: 1}).to.eql({b: 2}, 'nooo why fail??');
expect({a: 1}, 'nooo why fail??').to.eql({b: 2});
Псевдоним .eqls можно использовать взаимозаменяемо с .eql.
Проверка .deep.equal почти идентична .eql, но с одним отличием: .deep.equal заставляет использовать глубокие сравнения и для любых последующих проверок в цепочке.
.above(n[, msg])
Проверяет, что целевой объект — число или дата, больше заданного числа или даты соответственно. Однако, часто лучше проверить, что целевой объект равен ожидаемому значению.
expect(2).to.equal(2); // Recommended
expect(2).to.be.above(1); // Not recommended
Добавьте .lengthOf ранее в цепочке, чтобы проверить, что значение length или size целевого объекта больше заданного числа 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
Добавьте .not ранее в цепочке, чтобы инвертировать .above.
expect(2).to.equal(2); // Recommended
expect(1).to.not.be.above(2); // Not recommended
.above принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачной проверке. Сообщение также можно указать как второй аргумент к expect.
expect(1).to.be.above(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.above(2);
Псевдонимы .gt и .greaterThan можно использовать взаимозаменяемо с .above.
.least(n[, msg])
Проверяет, что целевой объект — число или дата, больше или равно заданному числу или дате соответственно. Однако, часто лучше проверить, что целевой объект равен ожидаемому значению.
expect(2).to.equal(2); // Recommended
expect(2).to.be.at.least(1); // Not recommended
expect(2).to.be.at.least(2); // Not recommended
Добавьте .lengthOf ранее в цепочке, чтобы проверить, что значение length или size целевого объекта больше или равно заданному числу 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
Добавьте .not ранее в цепочке, чтобы инвертировать .least.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.at.least(2); // Not recommended
.least принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачной проверке. Сообщение также можно указать как второй аргумент к expect.
expect(1).to.be.at.least(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.at.least(2);
Псевдонимы .gte и .greaterThanOrEqual можно использовать взаимозаменяемо с .least.
.below(n[, msg])
Проверяет, что целевой объект — число или дата, меньше заданного числа или даты соответственно. Однако, часто лучше проверить, что целевой объект равен ожидаемому значению.
expect(1).to.equal(1); // Recommended
expect(1).to.be.below(2); // Not recommended
Добавьте .lengthOf ранее в цепочке, чтобы проверить, что значение length или size целевого объекта меньше заданного числа 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
Добавьте .not ранее в цепочке, чтобы инвертировать .below.
expect(2).to.equal(2); // Recommended
expect(2).to.not.be.below(1); // Not recommended
.below принимает необязательный аргумент msg, который является пользовательским сообщением об ошибке, отображаемым при неудачной проверке. Сообщение также можно указать как второй аргумент к expect.
expect(2).to.be.below(1, 'nooo why fail??');
expect(2, 'nooo why fail??').to.be.below(1);
Псевдонимы .lt и .lessThan можно использовать взаимозаменяемо с .below.
.most(n[, msg])
Утверждает, что целевой объект является числом или датой, меньшей или равной заданному числу или дате соответственно. Однако часто лучше утверждать, что целевой объект равен ожидаемому значению.
expect(1).to.equal(1); // Recommended
expect(1).to.be.at.most(2); // Not recommended
expect(1).to.be.at.most(1); // Not recommended
Добавьте .lengthOf ранее в цепочке, чтобы утверждать, что значение целевого объекта length или size меньше или равно заданному числу 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
Добавьте .not ранее в цепочке, чтобы инвертировать .most.
expect(2).to.equal(2); // Recommended
expect(2).to.not.be.at.most(1); // Not recommended
.most принимает необязательный msg аргумент, который представляет собой пользовательское сообщение об ошибке, отображаемое при неудачном утверждении. Сообщение также может быть передано как второй аргумент функции expect.
expect(2).to.be.at.most(1, 'nooo why fail??');
expect(2, 'nooo why fail??').to.be.at.most(1);
Псевдонимы .lte и .lessThanOrEqual могут использоваться взаимозаменяемо с .most.
.within(start, finish[, msg])
Утверждает, что целевой объект является числом или датой, не меньшей чем заданное число или дата start, и не большей чем заданное число или дата finish соответственно. Однако часто лучше утверждать, что целевой объект равен ожидаемому значению.
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
Добавьте .lengthOf ранее в цепочке, чтобы утверждать, что значение целевого объекта length или size не меньше чем заданное число start, и не больше чем заданное число 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
Добавьте .not ранее в цепочке, чтобы инвертировать .within.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.within(2, 4); // Not recommended
.within принимает необязательный msg аргумент, представляющий пользовательское сообщение об ошибке, отображаемое при неудачном утверждении. Сообщение также можно передать как второй аргумент функции expect.
expect(4).to.be.within(1, 3, 'nooo why fail??');
expect(4, 'nooo why fail??').to.be.within(1, 3);
.instanceof(constructor[, msg])
Утверждает, что целевой объект является экземпляром заданного constructor.
function Cat () { }
expect(new Cat()).to.be.an.instanceof(Cat);
expect([1, 2]).to.be.an.instanceof(Array);
Добавьте .not ранее в цепочке, чтобы инвертировать .instanceof.
expect({a: 1}).to.not.be.an.instanceof(Array);
.instanceof принимает необязательный msg аргумент, представляющий собой пользовательское сообщение об ошибке, отображаемое при неудачном утверждении. Сообщение также можно передать как второй аргумент функции expect.
expect(1).to.be.an.instanceof(Array, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.an.instanceof(Array);
Из-за ограничений ES5, .instanceof может не работать как ожидается при использовании транспайлера, такого как Babel или TypeScript. В частности, он может давать неожиданные результаты при наследовании от встроенных объектов, таких как Array, Error, и Map. Обратитесь к документации вашего транспайлера для получения подробностей:
- (Babel)
- (TypeScript)
Псевдоним .instanceOf может использоваться взаимозаменяемо с .instanceof.
.property(name[, val[, msg]])
Утверждает, что целевой объект имеет свойство с заданным ключом name.
expect({a: 1}).to.have.property('a');
Если val предоставлено, .property также утверждает, что значение свойства равно заданному значению val.
expect({a: 1}).to.have.property('a', 1);
По умолчанию используется строгое (===) равенство. Для использования глубокого равенства добавьте .deep ранее в цепочке. См. страницу проекта deep-eql для получения информации об алгоритме глубокого равенства: 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});
Перечислимые и неперечислимые свойства целевого объекта всегда включаются в поиск. По умолчанию включаются собственные и унаследованные свойства. Чтобы исключить унаследованные свойства из поиска, добавьте .own ранее в цепочке.
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 и .own могут быть объединены.
expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1});
Для включения нотации точек и квадратных скобок при обращении к вложенным свойствам добавьте .nested ранее в цепочке.
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');
Если . или [] являются частью имени свойства, их можно экранировать, добавив перед ними две обратные косые черты.
expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]');
.deep и .nested могут быть объединены.
expect({a: {b: [{c: 3}]}})
.to.have.deep.nested.property('a.b[0]', {c: 3});
.own и .nested нельзя объединять.
Чтобы инвертировать .property, добавьте .not ранее в цепочке.
expect({a: 1}).to.not.have.property('b');
Однако, небезопасно инвертировать .property, когда предоставлено val. Проблема в том, что это создаёт неопределённые ожидания, утверждая, что целевой объект либо не имеет свойства с заданным ключом name, либо что он имеет свойство с заданным ключом name, но его значение не равно заданному val. Лучше определить точный ожидаемый результат и написать утверждение, которое принимает только этот точный результат.
Если от целевого объекта не ожидается наличие свойства с заданным ключом name, лучше утверждать об этом напрямую.
expect({b: 2}).to.not.have.property('a'); // Recommended
expect({b: 2}).to.not.have.property('a', 1); // Not recommended
Если от целевого объекта ожидается наличие свойства с заданным ключом name, лучше утверждать, что свойство имеет ожидаемое значение, а не утверждать, что оно не имеет одного из многих неожиданных значений.
expect({a: 3}).to.have.property('a', 3); // Recommended
expect({a: 3}).to.not.have.property('a', 1); // Not recommended
.property изменяет целевой объект для всех последующих утверждений на значение свойства из исходного целевого объекта.
expect({a: 1}).to.have.property('a').that.is.a('number');
.property принимает необязательный msg аргумент, являющийся пользовательским сообщением об ошибке при неудачном утверждении. Сообщение также может быть передано как второй аргумент функции expect. Если val не передаётся, используйте только вторую форму.
// 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??');
Это утверждение отличается от отсутствия val. Вместо этого, оно утверждает, что целевой объект имеет свойство b, равное undefined.
Утверждения .ownProperty и .haveOwnProperty могут использоваться взаимозаменяемо с .own.property.
.ownPropertyDescriptor(name[, descriptor[, msg]])
Утверждает, что у целевого объекта есть собственное описание свойства с заданным ключом name. В поиске учитываются перечисляемые и неперечисляемые свойства.
expect({a: 1}).to.have.ownPropertyDescriptor('a');
Когда descriptor предоставлен, .ownPropertyDescriptor также утверждает, что описание свойства глубоко равно заданному descriptor. См. страницу проекта deep-eql для информации об алгоритме глубокого равенства: https://github.com/chaijs/deep-eql.
expect({a: 1}).to.have.ownPropertyDescriptor('a', {
configurable: true,
enumerable: true,
writable: true,
value: 1,
});
Добавьте .not ранее в цепочке, чтобы инвертировать .ownPropertyDescriptor.
expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
Однако, опасно инвертировать .ownPropertyDescriptor при предоставлении descriptor. Проблема заключается в том, что это создает неопределённые ожидания, утверждая, что у целевого объекта нет описания свойства с заданным ключом name, или что у него есть описание свойства с заданным ключом name, но оно не глубоко равно заданному descriptor. Чаще всего лучше определить точный ожидаемый результат и написать утверждение, которое принимает только этот точный результат.
Когда от целевого объекта не ожидается наличия описания свойства с заданным ключом name, лучше утверждать именно это.
// 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,
});
Когда от целевого объекта ожидается наличие описания свойства с заданным ключом name, лучше утверждать, что свойство имеет ожидаемое описание, а не утверждать, что у него нет одного из многих неожиданных описаний.
// 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 изменяет целевой объект последующих утверждений в цепочке на значение описания свойства из исходного объекта.
expect({a: 1}).to.have.ownPropertyDescriptor('a')
.that.has.property('enumerable', true);
.ownPropertyDescriptor принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать как второй аргумент expect. Если descriptor не предоставляется, используйте только вторую форму.
// 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??');
Вышеуказанное утверждение не эквивалентно тому, что descriptor не предоставлено. Вместо этого, оно утверждает, что у целевого объекта есть описание свойства, которое глубоко равно undefined.
Псевдоним .haveOwnPropertyDescriptor может быть использован взаимозаменяемо с .ownPropertyDescriptor.
.lengthOf(n[, msg])
Утверждает, что длина целевого объекта или length равна заданному числу 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);
Добавьте .not ранее в цепочке, чтобы инвертировать .lengthOf. Однако, часто лучше утверждать, что свойство length целевого объекта равно его ожидаемому значению, а не не равно одному из многих неожиданных значений.
expect('foo').to.have.lengthOf(3); // Recommended
expect('foo').to.not.have.lengthOf(4); // Not recommended
.lengthOf принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также может быть задано в качестве второго аргумента expect.
expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??');
expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2);
.lengthOf также может быть использован как цепочка, заставляя все утверждения .above, .below, .least, .most, и .within в последующей цепочке использовать свойство length целевого объекта как целевой объект. Однако, часто лучше утверждать, что свойство length целевого объекта равно его ожидаемой длине, а не утверждать, что его свойство length находится в некотором диапазоне значений.
// 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);
Из-за проблемы совместимости псевдоним .length не может быть непосредственно присоединён к неприменённому методу, такому как .a. Поэтому, .length не может быть использован взаимозаменяемо с .lengthOf во всех ситуациях. Рекомендуется всегда использовать .lengthOf вместо .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])
Утверждает, что целевой объект соответствует заданному регулярному выражению re.
expect('foobar').to.match(/^foo/);
Добавьте .not ранее в цепочке, чтобы инвертировать .match.
expect('foobar').to.not.match(/taco/);
.match принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента expect.
expect('foobar').to.match(/taco/, 'nooo why fail??');
expect('foobar', 'nooo why fail??').to.match(/taco/);
Псевдоним .matches может быть использован взаимозаменяемо с .match.
.string(str[, msg])
Утверждает, что целевая строка содержит заданную подстроку str.
expect('foobar').to.have.string('bar');
Добавьте .not ранее в цепочке, чтобы инвертировать .string.
expect('foobar').to.not.have.string('taco');
.string принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента expect.
expect('foobar').to.have.string('taco', 'nooo why fail??');
expect('foobar', 'nooo why fail??').to.have.string('taco');
.keys(key1[, key2[, …]])
Утверждает, что целевой объект, массив, карта или множество имеют заданные ключи. В поиске учитываются только собственные наследоваемые свойства целевого объекта.
Когда целевой объект является объектом или массивом, ключи могут быть предоставлены как один или несколько строковых аргументов, один массив аргументов или один объект аргументов. В последнем случае важны только ключи в заданном объекте; значения игнорируются.
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
Когда целевой объект является картой или множеством, каждый ключ должен быть предоставлен как отдельный аргумент.
expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b');
expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b');
Поскольку .keys делает разные вещи в зависимости от типа целевого объекта, важно проверить тип целевого объекта перед использованием .keys. См. .a документацию для получения информации о проверке типа целевого объекта.
expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
По умолчанию для сравнения ключей карт и множеств используется строгое (===) равенство. Добавьте .deep ранее в цепочке, чтобы использовать глубокое равенство вместо этого. См. страницу проекта deep-eql для информации об алгоритме глубокого равенства: 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}]);
По умолчанию целевой объект должен иметь все заданные ключи и не больше. Добавьте .any ранее в цепочке, чтобы потребовать, чтобы целевой объект имел хотя бы один из заданных ключей. Кроме того, добавьте .not ранее в цепочке, чтобы отрицать .keys. Часто лучше добавлять .any при отрицании .keys, и использовать .all при утверждении .keys без отрицания.
При отрицании .keys, .any предпочтительнее, потому что .not.any.keys утверждает точно то, что ожидается от выходных данных, в то время как .not.all.keys создаёт неопределённые ожидания.
// 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');
При утверждении .keys без отрицания, .all предпочтительнее, потому что .all.keys утверждает точно то, что ожидается от выходных данных, в то время как .any.keys создаёт неопределённые ожидания.
// 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');
Обратите внимание, что .all используется по умолчанию, когда ни .all , ни .any не появляются ранее в цепочке. Однако часто лучше добавить .all, так как это улучшает читаемость.
// 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
Добавьте .include ранее в цепочке, чтобы потребовать, чтобы ключи целевого объекта были надмножеством ожидаемых ключей, а не идентичными множествами.
// 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');
Однако, если .any и .include объединены, только .any вступает в силу. .include игнорируется в этом случае.
// Both assertions are identical
expect({a: 1}).to.have.any.keys('a', 'b');
expect({a: 1}).to.include.any.keys('a', 'b');
Пользовательское сообщение об ошибке может быть передано вторым аргументом к expect.
expect({a: 1}, 'nooo why fail??').to.have.key('b');
Псевдоним .key может быть использован взаимозаменяемо с .keys.
.throw([errorLike], [errMsgMatcher], [msg])
Если аргументы не указаны, .throw вызывает целевую функцию и утверждает, что будет брошена ошибка.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
Если указан один аргумент, и это конструктор ошибки, .throw вызывает целевую функцию и утверждает, что будет брошена ошибка, являющаяся экземпляром этого конструктора ошибки.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(TypeError);
Если указан один аргумент, и это экземпляр ошибки, .throw вызывает целевую функцию и утверждает, что будет брошена ошибка, строго (===) равная этому экземпляру ошибки.
var err = new TypeError('Illegal salmon!');
var badFn = function () { throw err; };
expect(badFn).to.throw(err);
Если указан один аргумент, и это строка, .throw вызывает целевую функцию и утверждает, что будет брошена ошибка с сообщением, содержащим эту строку.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw('salmon');
Если указан один аргумент, и это регулярное выражение, .throw вызывает целевую функцию и утверждает, что будет брошена ошибка с сообщением, соответствующим этому регулярному выражению.
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw(/salmon/);
Если указаны два аргумента, и первый - экземпляр или конструктор ошибки, а второй - строка или регулярное выражение, .throw вызывает функцию и утверждает, что будет брошена ошибка, удовлетворяющая обоим условиям, как описано выше.
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/);
Добавьте .not ранее в цепочке, чтобы отрицать .throw.
var goodFn = function () {};
expect(goodFn).to.not.throw();
Однако опасно отрицать .throw, когда предоставлены какие-либо аргументы. Проблема в том, что это создаёт неопределённые ожидания, утверждая, что целевой объект либо не генерирует ошибку, либо генерирует ошибку, но другого типа, чем указанный, или что он генерирует ошибку указанного типа, но с сообщением, не включающим заданную строку. Часто лучше определить точный ожидаемый выходной результат и написать утверждение, которое принимает только этот точный результат.
Если от целевого объекта не ожидается генерации ошибки, часто лучше утверждать именно это.
var goodFn = function () {};
expect(goodFn).to.not.throw(); // Recommended
expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended
Если от целевого объекта ожидается генерация ошибки, часто лучше утверждать, что ошибка является ожидаемого типа и содержит ожидаемую строку в сообщении, а не утверждать, что она не имеет одного из многих неожиданных типов и не содержит некоторой строки в сообщении.
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 изменяет целевой объект последующих утверждений в цепочке на объект ошибки, который был сгенерирован.
var err = new TypeError('Illegal salmon!');
err.code = 42;
var badFn = function () { throw err; };
expect(badFn).to.throw(TypeError).with.property('code', 42);
.throw принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при провале утверждения. Сообщение также может быть передано вторым аргументом к expect . При отсутствии двух аргументов всегда используйте вторую форму.
var goodFn = function () {};
expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??');
expect(goodFn, 'nooo why fail??').to.throw();
Из-за ограничений ES5, .throw может не всегда работать как ожидается при использовании транспайлера, такого как Babel или TypeScript. В частности, могут возникнуть неожиданные результаты при наследовании встроенного объекта Error и последующей передаче подклассированного конструктора в .throw. Обратитесь к документации вашего транспайлера для получения подробностей:
- (Babel)
- (TypeScript)
Будьте внимательны к распространённым ошибкам при использовании утверждения throw. Распространённая ошибка — это случайное вызов функции самостоятельно вместо того, чтобы позволить утверждению throw вызвать функцию за вас. Например, при тестировании того, что функция с именем fn генерирует ошибку, используйте fn вместо fn(), как целевой объект утверждения.
expect(fn).to.throw(); // Good! Tests `fn` as desired
expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn`
Если необходимо утверждать, что ваша функция fn генерирует ошибку при передаче определённых аргументов, поместите вызов fn внутрь другой функции.
expect(function () { fn(42); }).to.throw(); // Function expression
expect(() => fn(42)).to.throw(); // ES6 arrow function
Ещё одна распространённая ошибка — это передача метода объекта (или любой самостоятельной функции, которая опирается на this ) как целевого объекта утверждения. Это проблематично, потому что контекст this будет потерян при вызове функции .throw; он не сможет узнать, что this должно быть. Существует два способа решения этой проблемы. Одно решение — это обернуть вызов метода или функции в другую функцию. Другое решение — использовать 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
Наконец, стоит упомянуть, что в JavaScript рекомендуется генерировать только Error и производные от Error, такие как ReferenceError, TypeError, и пользовательские объекты, расширяющие Error. Никакой другой тип значения не сгенерирует стек отслеживания при инициализации. При этом утверждение throw технически поддерживает любой тип значения, а не только Error и его производные.
Псевдонимы .throws и .Throw могут использоваться взаимозаменяемо с .throw.
.respondTo(method[, msg])
Когда целевой объект не является функцией, .respondTo проверяет, что у целевого объекта есть метод с указанным именем method. Метод может быть собственным или унаследованным, а также перечисляемым или нет.
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.respondTo('meow');
Когда целевой объект является функцией, .respondTo проверяет, что у свойства prototype целевого объекта есть метод с указанным именем method. Опять же, метод может быть собственным или унаследованным, а также перечисляемым или нет.
function Cat () {}
Cat.prototype.meow = function () {};
expect(Cat).to.respondTo('meow');
Добавьте .itself ранее в цепочке, чтобы заставить .respondTo обрабатывать целевой объект как не функцию, даже если это функция. Таким образом, она проверяет, что у целевого объекта есть метод с указанным именем method, а не проверяет, что у свойства prototype целевого объекта есть метод с указанным именем method.
function Cat () {}
Cat.prototype.meow = function () {};
Cat.hiss = function () {};
expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
Когда .itself не добавляется, важно проверить тип целевого объекта перед использованием .respondTo. См. документацию .a для информации о проверке типа целевого объекта.
function Cat () {}
Cat.prototype.meow = function () {};
expect(new Cat()).to.be.an('object').that.respondsTo('meow');
Добавьте .not ранее в цепочке, чтобы инвертировать .respondTo.
function Dog () {}
Dog.prototype.bark = function () {};
expect(new Dog()).to.not.respondTo('meow');
.respondTo принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при ошибочном утверждении. Сообщение также может быть передано как второй аргумент функции expect.
expect({}).to.respondTo('meow', 'nooo why fail??');
expect({}, 'nooo why fail??').to.respondTo('meow');
Псевдоним .respondsTo может использоваться взаимозаменяемо с .respondTo.
.itself
Заставляет все последующие утверждения .respondTo вести себя так, как будто целевой объект является не функцией, даже если он функция. Таким образом, он заставляет .respondTo проверять, что у целевого объекта есть метод с заданным именем, а не проверяет, что у свойства prototype целевого объекта есть метод с заданным именем.
function Cat () {}
Cat.prototype.meow = function () {};
Cat.hiss = function () {};
expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow');
.satisfy(matcher[, msg])
Вызывает переданную функцию matcher, передавая целевой объект в качестве первого аргумента, и проверяет, что возвращаемое значение истинно.
expect(1).to.satisfy(function(num) {
return num > 0;
});
Добавьте .not ранее в цепочке, чтобы инвертировать .satisfy.
expect(1).to.not.satisfy(function(num) {
return num > 2;
});
.satisfy принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при ошибочном утверждении. Сообщение также можно передать как второй аргумент функции 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;
});
Псевдоним .satisfies можно использовать взаимозаменяемо с .satisfy.
.closeTo(expected, delta[, msg])
Проверяет, что целевое число находится в заданном интервале +/- delta от заданного числа expected. Однако часто лучше проверить, что целевое значение равно ожидаемому.
// 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);
Добавьте .not ранее в цепочке, чтобы инвертировать .closeTo.
expect(1.5).to.equal(1.5); // Recommended
expect(1.5).to.not.be.closeTo(3, 1); // Not recommended
.closeTo принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при ошибочном утверждении. Сообщение также можно передать как второй аргумент функции expect.
expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??');
expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1);
Псевдоним .approximately может использоваться взаимозаменяемо с .closeTo.
.members(set[, msg])
Проверяет, что массив целевого объекта содержит те же элементы, что и заданный массив set.
expect([1, 2, 3]).to.have.members([2, 1, 3]);
expect([1, 2, 2]).to.have.members([2, 1, 2]);
По умолчанию сравнение элементов выполняется с использованием строгого (===) равенства. Добавление .deep ранее в цепочке использует глубокое сравнение. Смотрите страницу проекта deep-eql для получения информации об алгоритме глубокого сравнения: 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}]);
По умолчанию порядок элементов не важен. Добавление .ordered ранее в цепочке требует, чтобы элементы появлялись в том же порядке.
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]);
По умолчанию оба массива должны иметь одинаковую длину. Добавление .include ранее в цепочке требует, чтобы элементы целевого массива были супермножеством ожидаемых элементов. Обратите внимание, что дубликаты игнорируются в подмножестве, когда .include добавлено.
// 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, и .include могут быть объединены. Однако если .include и .ordered объединены, порядок элементов начинается с начала обоих массивов.
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}]);
Добавление .not ранее в цепочке инвертирует .members. Однако это опасно. Проблема в том, что это создает неопределённые ожидания, проверяя, что у целевого массива не все элементы одинаковы, как в заданном массиве set, но могут или не могут быть некоторые из них. Часто лучше определить точный ожидаемый результат и написать утверждение, которое принимает только этот точный результат.
expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended
expect([1, 2]).to.not.have.members([3, 4]); // Not recommended
.members принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при ошибочном утверждении. Сообщение также можно передать как второй аргумент функции 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])
Проверяет, что целевое значение является элементом заданного массива list. Однако часто лучше проверить, что целевое значение равно ожидаемому.
expect(1).to.equal(1); // Recommended
expect(1).to.be.oneOf([1, 2, 3]); // Not recommended
Сравнения выполняются с использованием строгого (===) равенства.
Добавьте .not ранее в цепочке, чтобы инвертировать .oneOf.
expect(1).to.equal(1); // Recommended
expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended
Также его можно использовать совместно с .contain или .include, что будет работать как с массивами, так и со строками:
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 принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при ошибочном утверждении. Сообщение также можно передать как второй аргумент функции 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]])
При одном аргументе, .change утверждает, что заданная функция subject возвращает разное значение при вызове до целевой функции и после. Однако часто лучше утверждать, что subject равно ожидаемому значению.
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);
При двух аргументах, .change утверждает, что значение свойства subject данного объекта prop отличается до и после вызова целевой функции.
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');
Используется строгое (===) равенство для сравнения значений до и после.
Добавьте .not ранее в цепочке, чтобы отрицать .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 принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента expect . При отсутствии двух аргументов всегда используйте вторую форму.
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 также заставляет все последующие .by утверждения в цепочке утверждать, насколько числовой предмет увеличился или уменьшился. Однако использование .change.by опасно. Проблема в том, что это создает неопределенные ожидания, утверждая, что предмет увеличивается на заданный дельту или уменьшается на заданный дельту. Часто лучше определить точный ожидаемый результат и написать утверждение, принимающее только этот точный результат.
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
Псевдоним .changes может быть использован взаимозаменяемо с .change.
.increase(subject[, prop[, msg]])
При одном аргументе, .increase утверждает, что заданная функция subject возвращает большее число после вызова целевой функции по сравнению с вызовом до неё. .increase также заставляет все последующие .by утверждения в цепочке утверждать, на сколько больше возвращается число. Часто лучше утверждать, что возвращаемое значение увеличилось на ожидаемое значение, а не на любое.
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
При двух аргументах, .increase утверждает, что значение свойства subject данного объекта prop больше после вызова целевой функции по сравнению с вызовом до неё.
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
Добавьте .not ранее в цепочке, чтобы отрицать .increase. Однако это опасно. Проблема в том, что это создает неопределенные ожидания, утверждая, что предмет либо уменьшается, либо остается прежним. Часто лучше определить точный ожидаемый результат и написать утверждение, принимающее только этот точный результат.
Если ожидается уменьшение предмета, то лучше утверждать, что оно уменьшилось на ожидаемое значение.
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
Если ожидается, что предмет останется прежним, то лучше утверждать именно это.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.not.change(myObj, 'val'); // Recommended
expect(noop).to.not.increase(myObj, 'val'); // Not recommended
.increase принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента expect . При отсутствии двух аргументов всегда используйте вторую форму.
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);
Псевдоним .increases может быть использован взаимозаменяемо с .increase.
.decrease(subject[, prop[, msg]])
При одном аргументе, .decrease утверждает, что заданная функция subject возвращает меньшее число после вызова целевой функции по сравнению с вызовом до неё. .decrease также заставляет все последующие .by утверждения в цепочке утверждать, на сколько меньше возвращается число. Часто лучше утверждать, что возвращаемое значение уменьшилось на ожидаемое значение, а не на любое.
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
При двух аргументах, .decrease утверждает, что значение свойства subject данного объекта prop меньше после вызова целевой функции по сравнению с вызовом до неё.
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
Добавьте .not ранее в цепочке, чтобы отрицать .decrease. Однако это опасно. Проблема в том, что это создает неопределенные ожидания, утверждая, что предмет либо увеличивается, либо остается прежним. Часто лучше определить точный ожидаемый результат и написать утверждение, принимающее только этот точный результат.
Если ожидается увеличение предмета, то лучше утверждать, что оно увеличилось на ожидаемое значение.
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
Если ожидается, что предмет останется прежним, то лучше утверждать именно это.
var myObj = {val: 1}
, noop = function () {};
expect(noop).to.not.change(myObj, 'val'); // Recommended
expect(noop).to.not.decrease(myObj, 'val'); // Not recommended
.decrease принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента expect . При отсутствии двух аргументов всегда используйте вторую форму.
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);
Псевдоним .decreases может быть использован взаимозаменяемо с .decrease.
.by(delta[, msg])
После утверждения .increase в цепочке, .by утверждает, что предмет утверждения .increase увеличился на указанную delta.
var myObj = {val: 1}
, addTwo = function () { myObj.val += 2; };
expect(addTwo).to.increase(myObj, 'val').by(2);
После утверждения .decrease в цепочке, .by утверждает, что предмет утверждения .decrease уменьшился на указанную delta.
var myObj = {val: 1}
, subtractTwo = function () { myObj.val -= 2; };
expect(subtractTwo).to.decrease(myObj, 'val').by(2);
После утверждения .change в цепочке, .by утверждает, что предмет утверждения .change увеличился или уменьшился на указанную delta . Однако использование .change.by опасно. Проблема в том, что это создает неопределенные ожидания. Часто лучше определить точный ожидаемый результат и написать утверждение, принимающее только этот точный результат.
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
Добавьте .not ранее в цепочке, чтобы отрицать .by. Однако часто лучше утверждать, что предмет изменился на ожидаемое значение дельты, а не на то, что он не изменился на одно из бесчисленных непредвиденных значений дельты.
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 принимает необязательный msg аргумент, который является пользовательским сообщением об ошибке, отображаемым при неудачном утверждении. Сообщение также можно указать в качестве второго аргумента 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
Утверждает, что целевой объект является расширяемым, то есть к нему можно добавлять новые свойства. Примитивы никогда не расширяемы.
expect({a: 1}).to.be.extensible;
Добавьте .not ранее в цепочке, чтобы отрицать .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;
Пользовательское сообщение об ошибке можно указать в качестве второго аргумента к expect.
expect(1, 'nooo why fail??').to.be.extensible;
.sealed
Утверждает, что целевой объект запечатан, что означает, что к нему нельзя добавить новые свойства, и его существующие свойства нельзя переконфигурировать или удалить. Однако возможно, что существующие свойства всё ещё можно переназначить на новые значения. Примитивы всегда запечатаны.
var sealedObject = Object.seal({});
var frozenObject = Object.freeze({});
expect(sealedObject).to.be.sealed;
expect(frozenObject).to.be.sealed;
expect(1).to.be.sealed;
Добавьте .not ранее в цепочке, чтобы отменить .sealed.
expect({a: 1}).to.not.be.sealed;
Пользовательское сообщение об ошибке может быть передано в качестве второго аргумента к expect.
expect({a: 1}, 'nooo why fail??').to.be.sealed;
.frozen
Утверждает, что целевой объект заморожен, что означает, что к нему нельзя добавить новые свойства, и его существующие свойства нельзя переназначить на новые значения, переконфигурировать или удалить. Примитивы всегда заморожены.
var frozenObject = Object.freeze({});
expect(frozenObject).to.be.frozen;
expect(1).to.be.frozen;
Добавьте .not ранее в цепочке, чтобы отменить .frozen.
expect({a: 1}).to.not.be.frozen;
Пользовательское сообщение об ошибке может быть передано в качестве второго аргумента к expect.
expect({a: 1}, 'nooo why fail??').to.be.frozen;
.finite
Утверждает, что целевое значение является числом и не является NaN или положительной/отрицательной Infinity.
expect(1).to.be.finite;
Добавьте .not ранее в цепочке, чтобы отменить .finite. Однако это опасно. Проблема заключается в том, что это создает неопределённые ожидания, утверждая, что объект либо не является числом, либо является NaN, либо положительной Infinity, либо отрицательной Infinity. Чаще всего лучше определить точный ожидаемый результат и написать утверждение, которое принимает только этот точный результат.
Когда целевой объект не должен быть числом, лучше утверждать, что он является ожидаемым типом, а не утверждать, что он не является одним из многих неожиданных типов.
expect('foo').to.be.a('string'); // Recommended
expect('foo').to.not.be.finite; // Not recommended
Когда ожидается, что целевой объект будет NaN, лучше утверждать именно это.
expect(NaN).to.be.NaN; // Recommended
expect(NaN).to.not.be.finite; // Not recommended
Когда ожидается, что целевой объект будет положительной бесконечностью, лучше утверждать именно это.
expect(Infinity).to.equal(Infinity); // Recommended
expect(Infinity).to.not.be.finite; // Not recommended
Когда ожидается, что целевой объект будет отрицательной бесконечностью, лучше утверждать именно это.
expect(-Infinity).to.equal(-Infinity); // Recommended
expect(-Infinity).to.not.be.finite; // Not recommended
Пользовательское сообщение об ошибке может быть передано в качестве второго аргумента к expect.
expect('foo', 'nooo why fail??').to.be.finite;
.fail([message])
.fail(actual, expected, [message], [operator])
Вызвать ошибку.
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])
Вызвать ошибку.
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, ">");
© 2017 Chai.js Assertion Library
Licensed under the MIT License.
https://www.chaijs.com/api/bdd/