Assert
Модуль assert предоставляет простой набор проверочных тестов, которые могут быть использованы для проверки инвариантов.
Существует strict и legacy режим, но рекомендуется использовать только strict mode.
Для получения дополнительной информации о используемых сравнениях равенства см. руководство MDN по сравнениям равенства и тождественности.
Строгий режим
При использовании strict mode, любая функция assert будет использовать сравнение равенства, используемое в строгом режиме функции. Таким образом, assert.deepEqual(), например, будет работать так же, как assert.deepStrictEqual().
Доступ к нему можно получить следующим образом:
const assert = require('assert').strict;
Режим по умолчанию
При прямом обращении к assert вместо использования свойства strict, для любой функции без "strict" в её имени, например, assert.deepEqual(), будет использовано абстрактное сравнение на равенство.
Доступ к нему можно получить следующим образом:
const assert = require('assert');
Рекомендуется использовать strict mode, так как абстрактное сравнение на равенство часто может давать неожиданные результаты. Это особенно справедливо для assert.deepEqual(), где правила сравнения довольно нестрогие:
// WARNING: This does not throw an AssertionError! assert.deepEqual(/a/gi, new Date());
assert(value[, message])
-
value<any> -
message<any>
Псевдоним для assert.ok().
assert.deepEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Строгий режим
Псевдоним для assert.deepStrictEqual().
Режим по умолчанию
assert.deepStrictEqual() вместо этого.Проверяет глубокое равенство параметров actual и expected. Примитивные значения сравниваются с помощью абстрактного сравнения на равенство ( == ).
Рассматриваются только перечисляемые "собственные" свойства. Реализация assert.deepEqual() не проверяет [[Prototype]] объектов, присоединённые символы или неперечисляемые свойства — для таких проверок используйте assert.deepStrictEqual(). Это может привести к некоторым потенциально неожиданным результатам. Например, в следующем примере не происходит выброс AssertionError, так как свойства объекта RegExp не перечисляются:
// WARNING: This does not throw an AssertionError! assert.deepEqual(/a/gi, new Date());
Исключение делается для Map и Set. Элементы Map и Set сравниваются, как ожидалось.
"Глубокое" равенство означает, что также оцениваются перечисляемые "собственные" свойства вложенных объектов:
const assert = require('assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK, object is equal to itself
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
// values of b are different
assert.deepEqual(obj1, obj3);
// OK, objects are equal
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
// Prototypes are ignored
Если значения не равны, выбрасывается AssertionError с свойством message , установленным равным значению параметра message. Если параметр message не определён, назначается сообщение об ошибке по умолчанию.
assert.deepStrictEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
В целом идентично assert.deepEqual() с некоторыми исключениями:
Подробности сравнения
- Примитивные значения сравниваются с помощью строгого сравнения на равенство (
===). - Значения Set и ключи Map сравниваются с помощью сравнения SameValueZero (что означает отсутствие ограничений).
- Теги типов объектов должны быть одинаковыми.
-
[[Prototype]]объектов сравниваются с помощью строгого сравнения на равенство. - Рассматриваются только перечисляемые "собственные" свойства.
- [
Error][] сообщения всегда сравниваются, несмотря на то, что это неперечисляемое свойство. - Обёртки объектов примитивных типов сравниваются как объекты и как значения без обёртки.
- Свойства объектов сравниваются без учёта порядка.
- Ключи Map и элементы Set сравниваются без учёта порядка.
- Рекурсия прекращается, когда оба значения различаются или оба значения сталкиваются с циклической ссылкой.
const assert = require('assert').strict;
assert.deepEqual({ a: 1 }, { a: '1' });
// OK, because 1 == '1'
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
// because 1 !== '1' using strict equality
// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);
assert.deepEqual(object, fakeDate);
// OK, doesn't check [[Prototype]]
assert.deepStrictEqual(object, fakeDate);
// AssertionError: {} deepStrictEqual Date {}
// Different [[Prototype]]
assert.deepEqual(date, fakeDate);
// OK, doesn't check type tags
assert.deepStrictEqual(date, fakeDate);
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
// Different type tags
assert.deepStrictEqual(new Number(1), new Number(2));
// Fails because the wrapped number is unwrapped and compared as well.
assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.
Если значения не равны, выбрасывается AssertionError с свойством message , установленным равным значению параметра message. Если параметр message не определён, назначается сообщение об ошибке по умолчанию.
assert.doesNotReject(block[, error][, message])
Ожидает завершения выполнения возвращаемого функцией block промиса без его отклонения. Подробнее см. assert.rejects().
При вызове assert.doesNotReject(), функция block будет немедленно вызвана и ожидать завершения.
Помимо асинхронной природы ожидания завершения, поведение идентично [assert.doesNotThrow()][].
(async () => {
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError
);
})();
assert.doesNotReject(
() => Promise.reject(new TypeError('Wrong value')),
SyntaxError
).then(() => {
// ...
});
assert.doesNotThrow(block[, error][, message])
Утверждает, что функция block не вызывает ошибку. Подробнее см. assert.throws().
Обратите внимание: использование assert.doesNotThrow() на самом деле неэффективно, поскольку нет выгоды в перехвате ошибки и последующем её повторном выбросе. Вместо этого рассмотрите возможность добавления комментария рядом со специфической веткой кода, которая не должна вызывать ошибку, и сохраняйте сообщения об ошибках максимально информативными.
При вызове assert.doesNotThrow() он немедленно вызовет функцию block.
Если возникает ошибка, и она является того же типа, что и указано параметром error, то будет выброшено исключение AssertionError. Если ошибка другого типа или параметр error не определен, ошибка передаётся обратно вызывающей стороне.
Например, следующее приведёт к выбросу TypeError, так как в утверждении нет соответствующего типа ошибки:
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError
);
Однако, следующее приведёт к выбросу AssertionError с сообщением 'Получена нежелательная ошибка (TypeError)..':
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError
);
Если выброшено AssertionError и предоставлено значение для параметра message, значение message будет добавлено к сообщению AssertionError.
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError,
'Whoops'
);
// Throws: AssertionError: Got unwanted exception (TypeError). Whoops
assert.equal(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Жесткий режим
Псевдоним для assert.strictEqual().
Устаревший режим
assert.strictEqual() вместо этого.Проверяет поверхностное, принудительное равенство между параметрами actual и expected с помощью Абстрактного сравнения на равенство ( == ).
const assert = require('assert');
assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
//AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
Если значения не равны, выбрасывается AssertionError с свойством message, установленным равным значению параметра message. Если параметр message не определён, используется сообщение об ошибке по умолчанию.
assert.fail(message)
assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])
-
actual<any> -
expected<any> -
message<any> -
operator<string> По умолчанию:'!=' -
stackStartFunction<Function> По умолчанию:assert.fail
Выбрасывает AssertionError. Если message ложно, сообщение об ошибке устанавливается как значения actual и expected, разделённые предоставленным operator. Если предоставлены только два аргумента actual и expected, operator будет по умолчанию '!='. Если предоставлен только message, он будет использован как сообщение об ошибке, другие аргументы будут сохранены как свойства в выброшенном объекте. Если stackStartFunction предоставлен, все кадровые фреймы выше этой функции будут удалены из трассировки стека (см. Error.captureStackTrace).
const assert = require('assert').strict;
assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2
assert.fail(1, 2, 'fail');
// AssertionError [ERR_ASSERTION]: fail
assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops
Примечание: В последних двух случаях actual, expected, и operator не влияют на сообщение об ошибке.
assert.fail();
// AssertionError [ERR_ASSERTION]: Failed
assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom
assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'
Пример использования stackStartFunction для усечения трассировки стека исключения:
function suppressFrame() {
assert.fail('a', 'b', undefined, '!==', suppressFrame);
}
suppressFrame();
// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
// at repl:1:1
// at ContextifyScript.Script.runInThisContext (vm.js:44:33)
// ...
assert.ifError(value)
-
value<any>
Выбрасывает value если value истинно. Это полезно при тестировании аргумента error в обратных вызовах.
const assert = require('assert').strict;
assert.ifError(null);
// OK
assert.ifError(0);
// OK
assert.ifError(1);
// Throws 1
assert.ifError('error');
// Throws 'error'
assert.ifError(new Error());
// Throws Error
assert.notDeepEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Жесткий режим
Псевдоним для assert.notDeepStrictEqual().
Устаревший режим
assert.notDeepStrictEqual() вместо этого.Проверяет глубокое неравенство. Противоположность assert.deepEqual().
const assert = require('assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj2);
// OK: obj1 and obj2 are not deeply equal
assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
assert.notDeepEqual(obj1, obj4);
// OK: obj1 and obj4 are not deeply equal
Если значения глубоко равны, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определен, используется сообщение об ошибке по умолчанию.
assert.notDeepStrictEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Проверяет глубокое строгое неравенство. Противоположность assert.deepStrictEqual().
const assert = require('assert').strict;
assert.notDeepEqual({ a: 1 }, { a: '1' });
// AssertionError: { a: 1 } notDeepEqual { a: '1' }
assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
Если значения глубоко и строго равны, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определен, используется сообщение об ошибке по умолчанию.
assert.notEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Жесткий режим
Псевдоним для assert.notStrictEqual().
Устаревший режим
assert.notStrictEqual() вместо этого.Проверяет поверхностное, принудительное неравенство с помощью Абстрактного сравнения на равенство ( != ).
const assert = require('assert');
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'
Если значения равны, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определён, используется сообщение об ошибке по умолчанию.
assert.notStrictEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Проверяет строгое неравенство, определяемое Строгим сравнением на равенство ( !== ).
const assert = require('assert').strict;
assert.notStrictEqual(1, 2);
// OK
assert.notStrictEqual(1, 1);
// AssertionError: 1 !== 1
assert.notStrictEqual(1, '1');
// OK
Если значения строго равны, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определён, используется сообщение об ошибке по умолчанию.
assert.ok(value[, message])
-
value<any> -
message<any>
Проверяет, является ли value истинным. Эквивалентно assert.equal(!!value, true, message).
Если value не истинно, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определен, используется сообщение об ошибке по умолчанию.
const assert = require('assert').strict;
assert.ok(true);
// OK
assert.ok(1);
// OK
assert.ok(false);
// throws "AssertionError: false == true"
assert.ok(0);
// throws "AssertionError: 0 == true"
assert.ok(false, 'it\'s false');
// throws "AssertionError: it's false"
assert.strictEqual(actual, expected[, message])
-
actual<any> -
expected<any> -
message<any>
Проверяет строгое равенство, определяемое Строгим сравнением на равенство ( === ).
const assert = require('assert').strict;
assert.strictEqual(1, 2);
// AssertionError: 1 === 2
assert.strictEqual(1, 1);
// OK
assert.strictEqual(1, '1');
// AssertionError: 1 === '1'
Если значения не строго равны, выбрасывается AssertionError со свойством message, установленным равным значению параметра message. Если параметр message не определен, используется сообщение об ошибке по умолчанию.
assert.rejects(block[, error][, message])
Ожидает, что обещание, возвращаемое функцией block, будет отклонено.
Когда вызывается assert.rejects(), она немедленно вызывает функцию block, и ожидает её завершения.
Помимо асинхронного характера ожидания завершения, поведение идентично assert.throws().
Если указано, error может быть конструктором, RegExp, функцией валидации или объектом, где каждый свойство будет проверено.
Если указано, message будет сообщением, предоставленным AssertionError, если блок не отклонится.
(async () => {
await assert.rejects(
async () => {
throw new Error('Wrong value');
},
Error
);
})();
assert.rejects(
() => Promise.reject(new Error('Wrong value')),
Error
).then(() => {
// ...
});
assert.throws(block[, error][, message])
Ожидает, что функция block бросит ошибку.
Если указано, error может быть конструктором, RegExp, функцией валидации или объектом, где каждый свойство будет проверено.
Если указано, message будет сообщением, предоставленным AssertionError, если блок не бросит ошибку.
Проверка instanceof с помощью конструктора:
assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);
Проверка сообщения об ошибке с помощью RegExp:
assert.throws(
() => {
throw new Error('Wrong value');
},
/value/
);
Пользовательская валидация ошибок:
assert.throws(
() => {
throw new Error('Wrong value');
},
function(err) {
if ((err instanceof Error) && /value/.test(err)) {
return true;
}
},
'unexpected error'
);
Пользовательский объект/экземпляр ошибки:
assert.throws(
() => {
const err = new TypeError('Wrong value');
err.code = 404;
throw err;
},
{
name: 'TypeError',
message: 'Wrong value'
// Note that only properties on the error object will be tested!
}
);
Обратите внимание, что error не может быть строкой. Если в качестве второго аргумента передаётся строка, то error предполагается пропущенным, и строка будет использована для message вместо этого. Это может привести к легко пропущенным ошибкам. Пожалуйста, внимательно прочтите пример ниже, если использование строки в качестве второго аргумента рассматривается:
function throwingFirst() {
throw new Error('First');
}
function throwingSecond() {
throw new Error('Second');
}
function notThrowing() {}
// The second argument is a string and the input function threw an Error.
// In that case both cases do not throw as neither is going to try to
// match for the error message thrown by the input function!
assert.throws(throwingFirst, 'Second');
assert.throws(throwingSecond, 'Second');
// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second
// If it was intended to match for the error message do this instead:
assert.throws(throwingSecond, /Second$/);
// Does not throw because the error messages match.
assert.throws(throwingFirst, /Second$/);
// Throws a error:
// Error: First
// at throwingFirst (repl:2:9)
Из-за запутанной записи рекомендуется не использовать строку в качестве второго аргумента. Это может привести к трудноуловимым ошибкам.
Ограничения
В следующих случаях рекомендуется использовать ES2015 Object.is(), который использует сравнение SameValueZero.
const a = 0; const b = -a; assert.notStrictEqual(a, b); // AssertionError: 0 !== -0 // Strict Equality Comparison doesn't distinguish between -0 and +0... assert(!Object.is(a, b)); // but Object.is() does! const str1 = 'foo'; const str2 = 'foo'; assert.strictEqual(str1 / 1, str2 / 1); // AssertionError: NaN === NaN // Strict Equality Comparison can't be used to check NaN... assert(Object.is(str1 / 1, str2 / 1)); // but Object.is() can!
Для получения дополнительной информации см. руководство MDN по сравнениям равенства и тождественности.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v8.x/docs/api/assert.html