Node.js v8.x 中文文档


assert - 断言#

稳定性: 2 - 稳定的

assert 模块提供了断言测试的函数,用于测试不变式。

assert(value[, message])#

  • value <any>
  • message <any>

assert.ok() 的别名。

assert.deepEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

测试 actual 参数与 expected 参数是否深度相等。 原始值使用相等运算符==)比较。

只测试可枚举的自身属性,不测试对象的原型、连接符、或不可枚举的属性(这些情况使用 assert.deepStrictEqual())。 例如,下面的例子不会抛出 AssertionError,因为 RegExp 对象的属性不是可枚举的:

// 不会抛出 AssertionError。
assert.deepEqual(/a/gi, new Date());

MapSet 包含的子项也会被测试。

子对象中可枚举的自身属性也会被测试:

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);
// 测试通过,对象与自身相等。

assert.deepEqual(obj1, obj2);
// 抛出 AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
// 因为 b 属性的值不同。

assert.deepEqual(obj1, obj3);
// 测试通过,两个对象相等。

assert.deepEqual(obj1, obj4);
// 抛出 AssertionError: { a: { b: 1 } } deepEqual {}
// 因为不测试原型。

如果两个值不相等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.deepStrictEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

assert.deepEqual() 大致相同,但有一些区别:

  1. 原始值使用全等运算符===)比较。Set 的值与 Map 的键使用 SameValueZero 比较。
  2. 对象的原型也使用全等运算符比较。
  3. 对象的类型标签要求相同。
  4. 比较[对象包装器][]时,其对象和里面的值要求相同。
const assert = require('assert');

assert.deepEqual({ a: 1 }, { a: '1' });
// 测试通过,因为 1 == '1'。

assert.deepStrictEqual({ a: 1 }, { a: '1' });
// 抛出 AssertionError: { a: 1 } deepStrictEqual { a: '1' }
// 因为使用全等运算符 1 !== '1'。

// 以下对象都没有自身属性。
const date = new Date();
const object = {};
const fakeDate = {};

Object.setPrototypeOf(fakeDate, Date.prototype);

assert.deepEqual(object, fakeDate);
// 测试通过,不测试原型。
assert.deepStrictEqual(object, fakeDate);
// 抛出 AssertionError: {} deepStrictEqual Date {}
// 因为原型不同。

assert.deepEqual(date, fakeDate);
// 测试通过,不测试类型标签。
assert.deepStrictEqual(date, fakeDate);
// 抛出 AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
// 因为类型标签不同。

assert.deepStrictEqual(new Number(1), new Number(2));
// 测试不通过,因为数值对象包装器里面的数值也会被比较。
assert.deepStrictEqual(new String('foo'), Object('foo'));
// 测试通过,因为这两个对象和里面的字符串都是相同的

如果两个值不相等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.doesNotThrow(block[, error][, message])#

断言 block 函数不会抛出错误。

assert.doesNotThrow() 被调用时,它会立即调用 block 函数。

如果抛出错误且错误类型与 error 参数指定的相同,则抛出 AssertionError。 如果错误类型不相同,或 error 参数为 undefined,则抛出错误。

以下例子会抛出 TypeError,因为在断言中没有匹配的错误类型:

assert.doesNotThrow(
  () => {
    throw new TypeError('错误信息');
  },
  SyntaxError
);

以下例子会抛出一个带有 Got unwanted exception (TypeError).. 信息的 AssertionError

assert.doesNotThrow(
  () => {
    throw new TypeError('错误信息');
  },
  TypeError
);

如果抛出了 AssertionError 且有给 message 参数传值,则 message 参数的值会被附加到 AssertionError 的信息中:

assert.doesNotThrow(
  () => {
    throw new TypeError('错误信息');
  },
  TypeError,
  '抛出错误'
);
// 抛出 AssertionError: Got unwanted exception (TypeError). 抛出错误

assert.equal(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

使用相等运算符==)测试 actual 参数与 expected 参数是否相等。

const assert = require('assert');

assert.equal(1, 1);
// 测试通过,1 == 1。
assert.equal(1, '1');
// 测试通过,1 == '1'。

assert.equal(1, 2);
// 抛出 AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// 抛出 AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

如果两个值不相等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

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 参数 + operator 参数 + expected 参数。 如果只提供了 actual 参数与 expected 参数,则 operator 参数默认为 '!='。 如果提供了 message 参数,则它会作为错误信息,其他参数会保存在错误对象的属性中。 如果提供了 stackStartFunction 参数,则该函数上的栈帧都会从栈信息中移除(详见 Error.captureStackTrace)。

const assert = require('assert');

assert.fail(1, 2, undefined, '>');
// 抛出 AssertionError [ERR_ASSERTION]: 1 > 2

assert.fail(1, 2, '错误信息');
// 抛出 AssertionError [ERR_ASSERTION]: 错误信息

assert.fail(1, 2, '错误信息', '>');
// 抛出 AssertionError [ERR_ASSERTION]: 错误信息
// 上面两个例子的 `actual` 参数、`expected` 参数与 `operator` 参数不影响错误消息。

assert.fail();
// 抛出 AssertionError [ERR_ASSERTION]: Failed

assert.fail('错误信息');
// 抛出 AssertionError [ERR_ASSERTION]: 错误信息

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');

assert.ifError(null);
// 测试通过。
assert.ifError(0);
// 测试通过。
assert.ifError(1);
// 抛出 1。
assert.ifError('error');
// 抛出 'error'。
assert.ifError(new Error());
// 抛出 Error。

assert.notDeepEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

测试 actual 参数与 expected 参数是否不深度相等。 与 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);
// 测试通过,obj1 与 obj2 不深度相等。

assert.notDeepEqual(obj1, obj3);
// 抛出 AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.notDeepEqual(obj1, obj4);
// 测试通过,obj1 与 obj4 不深度相等。

如果两个值深度相等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.notDeepStrictEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

测试 actual 参数与 expected 参数是否不深度全等。 与 assert.deepStrictEqual() 相反。

const assert = require('assert');

assert.notDeepEqual({ a: 1 }, { a: '1' });
// 抛出 AssertionError: { a: 1 } notDeepEqual { a: '1' }

assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// 测试通过。

如果两个值深度全等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.notEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

使用不等运算符!=)测试 actual 参数与 expected 参数是否不相等。

const assert = require('assert');

assert.notEqual(1, 2);
// 测试通过。

assert.notEqual(1, 1);
// 抛出 AssertionError: 1 != 1

assert.notEqual(1, '1');
// 抛出 AssertionError: 1 != '1'

如果两个值相等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.notStrictEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

使用不全等运算符!==)测试 actual 参数与 expected 参数是否不全等。

const assert = require('assert');

assert.notStrictEqual(1, 2);
// 测试通过。

assert.notStrictEqual(1, 1);
// 抛出 AssertionError: 1 !== 1

assert.notStrictEqual(1, '1');
// 测试通过。

如果两个值全等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.ok(value[, message])#

  • value <any>
  • message <any>

测试 value 是否为真值。 相当于 assert.equal(!!value, true, message)

如果 value 不为真值,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

const assert = require('assert');

assert.ok(true);
// 测试通过。
assert.ok(1);
// 测试通过。
assert.ok(false);
// 抛出 "AssertionError: false == true"
assert.ok(0);
// 抛出 "AssertionError: 0 == true"
assert.ok(false, '不是真值');
// 抛出 "AssertionError: 不是真值"

assert.strictEqual(actual, expected[, message])#

  • actual <any>
  • expected <any>
  • message <any>

使用全等运算符===)测试 actual 参数与 expected 参数是否全等。

const assert = require('assert');

assert.strictEqual(1, 2);
// 抛出 AssertionError: 1 === 2

assert.strictEqual(1, 1);
// 测试通过。

assert.strictEqual(1, '1');
// 抛出 AssertionError: 1 === '1'

如果两个值不全等,则抛出一个带有 message 属性的 AssertionError,其中 message 属性的值等于传入的 message 参数的值。 如果 message 参数为 undefined,则赋予默认的错误信息。

assert.throws(block[, error][, message])#

断言 block 函数会抛出错误。

error 参数可以是构造函数、正则表达式、或自定义函数。

如果指定了 message 参数,则当 block 函数不抛出错误时,message 参数会作为 AssertionError 的错误信息。

例子,error 参数为构造函数:

assert.throws(
  () => {
    throw new Error('错误信息');
  },
  Error
);

例子,error 参数为正则表达式:

assert.throws(
  () => {
    throw new Error('错误信息');
  },
  /错误/
);

例子,error 参数为自定义函数:

assert.throws(
  () => {
    throw new Error('错误信息');
  },
  function(err) {
    if ((err instanceof Error) && /错误/.test(err)) {
      return true;
    }
  },
  '不是期望的错误'
);

error 参数不能是字符串。 如果第二个参数是字符串,则视为省略 error 参数,传入的字符串会被用于 message 参数。 例如:

// 这是错误的!不要这么做!
assert.throws(myFunction, '错误信息', '没有抛出期望的信息');

// 应该这么做。
assert.throws(myFunction, /错误信息/, '没有抛出期望的信息');

注意事项#

对于 SameValueZero 比较,建议使用 ES2015 的 Object.is()

const a = 0;
const b = -a;
assert.notStrictEqual(a, b);
// 抛出 AssertionError: 0 !== -0
// 因为全等运算符不区分 -0 与 +0。
assert(!Object.is(a, b));
// 但 Object.is() 可以区分。

const str1 = 'foo';
const str2 = 'foo';
assert.strictEqual(str1 / 1, str2 / 1);
// 抛出 AssertionError: NaN === NaN
// 因为全等运算符不能用于测试 NaN。
assert(Object.is(str1 / 1, str2 / 1));
// 但 Object.is() 可以测试。

详见MDN的等式比较指南