Node.js v10.16.3 文档


assert(断言)#

中英对照提交修改

稳定性: 2 - 稳定

assert 模块提供了一组简单的断言测试,可用于测试不变量。

存在严格模式(strict)和遗留模式(legacy),但建议仅使用严格模式

有关使用的相等性比较的更多信息,参阅 MDN 的指南 - 相等性比较和相同性

assert.AssertionError 类#

中英对照提交修改

Error 的子类,表明断言的失败。 assert 模块抛出的所有错误都是 AssertionError 类的实例。

new assert.AssertionError(options)#

中英对照提交修改

  • options <Object>

    • message <string> 如果提供,则将错误消息设置为此值。
    • actual <any> 错误实例上的 actual 属性将包含此值。在内部用于 actual 错误输入,例如使用 assert.strictEqual()
    • expected <any> 错误实例上的 expected 属性将包含此值。在内部用于 expected 错误输入,例如使用 assert.strictEqual()
    • operator <string> 错误实例上的 operator 属性将包含此值。在内部用于表明用于比较的操作(或触发错误的断言函数)。
    • stackStartFn <Function> 如果提供,则生成的堆栈跟踪将移除所有帧直到提供的函数。

Error 的子类,表明断言的失败。

所有实例都包含内置的 Error 属性(messagename)以及:

const assert = require('assert');

// 生成 AssertionError 以便稍后比较错误的消息:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual'
});

// 验证错误的输出:
try {
  assert.strictEqual(1, 2);
} catch (err) {
  assert(err instanceof assert.AssertionError);
  assert.strictEqual(err.message, message);
  assert.strictEqual(err.name, 'AssertionError [ERR_ASSERTION]');
  assert.strictEqual(err.actual, 1);
  assert.strictEqual(err.expected, 2);
  assert.strictEqual(err.code, 'ERR_ASSERTION');
  assert.strictEqual(err.operator, 'strictEqual');
  assert.strictEqual(err.generatedMessage, true);
}

严格模式#

中英对照提交修改

当使用严格模式(strict mode)时,任何 assert 函数都将使用严格函数模式中使用的相等性。 因此,assert.deepEqual() 将与 assert.deepStrictEqual() 一样效果。

最重要的是,涉及对象的错误消息将产生错误的差异,而不是显示两个对象。 遗留模式则不是这种情况。

它可以使用以下方式访问:

const assert = require('assert').strict;

错误差异的示例:

const assert = require('assert').strict;

assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual ... Lines skipped
//
//   [
//     [
// ...
//       2,
// -     3
// +     '3'
//     ],
// ...
//     5
//   ]

要停用颜色,则使用 NODE_DISABLE_COLORS 环境变量。 注意,这也将停用 REPL 中的颜色。

遗留模式#

中英对照提交修改

稳定性: 0 - 废弃: 改为使用严格模式。

当直接访问 assert 而不是使用 strict 属性时,将对名称中没有 "strict" 的任何函数(例如 assert.deepEqual())使用抽象的相等性比较

它可以使用以下方式访问:

const assert = require('assert');

建议使用严格模式,因为抽象的相等性比较通常会产生意外的结果。 特别是对于 assert.deepEqual(),其中的比较规则是松散的:

// 注意:这不会抛出 AssertionError!
assert.deepEqual(/a/gi, new Date());

assert(value[, message])#

中英对照提交修改

assert.ok() 的别名。

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

暂无中英对照

Strict mode

An alias of assert.deepStrictEqual().

Legacy mode

稳定性: 0 - 废弃: 改为使用 assert.deepStrictEqual()

Tests for deep equality between the actual and expected parameters. Primitive values are compared with the Abstract Equality Comparison ( == ).

Only enumerable "own" properties are considered. The assert.deepEqual() implementation does not test the [[Prototype]] of objects or enumerable own Symbol properties. For such checks, consider using assert.deepStrictEqual() instead. assert.deepEqual() can have potentially surprising results. The following example does not throw an AssertionError because the properties on the RegExp object are not enumerable:

// WARNING: This does not throw an AssertionError!
assert.deepEqual(/a/gi, new Date());

An exception is made for Map and Set. Maps and Sets have their contained items compared too, as expected.

"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:

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

// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3);
// OK

// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

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

中英对照提交修改

测试 actual 参数和 expected 参数之间的深度相等。 深度相等意味着子对象的可枚举的自身属性也通过以下规则进行递归计算。

比较运算的详细说明#

中英对照提交修改

  • 使用 SameValue比较(使用 Object.is())来比较原始值。
  • 对象的类型标签应该相同。
  • 使用严格相等比较来比较对象的原型
  • 只考虑可枚举的自身属性
  • 始终比较 Error 的名称和消息,即使这些不是可枚举的属性。
  • 可枚举的自身 Symbol 属性也会比较。
  • 对象封装器作为对象和解封装后的值都进行比较。
  • Object 属性的比较是无序的。
  • Map 键名与 Set 子项的比较是无序的。
  • 当两边的值不相同或遇到循环引用时,递归停止。
  • WeakMapWeakSet 的比较不依赖于它们的值。请参阅下文了解更多详情。
const assert = require('assert').strict;

// 失败,因为 1 !== '1'。
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
//   {
// -   a: 1
// +   a: '1'
//   }

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

// 原型不同:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
// - {}
// + Date {}

// 类型标签不同:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
// - 2018-04-26T00:49:08.604Z
// + Date {}

assert.deepStrictEqual(NaN, NaN);
// 通过,因为使用 SameValue 比较。

// 解封装后的数字不同:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
// - [Number: 1]
// + [Number: 2]

assert.deepStrictEqual(new String('foo'), Object('foo'));
// 通过,因为对象与解封装后的字符串都是相同的。

assert.deepStrictEqual(-0, -0);
// 通过。

// 使用 SameValue 比较的零不同:
assert.deepStrictEqual(0, -0);
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
// - 0
// + -0

const symbol1 = Symbol();
const symbol2 = Symbol();
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
// 通过,因为在两个对象上的 symbol 相同。
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
// AssertionError [ERR_ASSERTION]: Input objects not identical:
// {
//   [Symbol()]: 1
// }

const weakMap1 = new WeakMap();
const weakMap2 = new WeakMap([[{}, {}]]);
const weakMap3 = new WeakMap();
weakMap3.unequal = true;

assert.deepStrictEqual(weakMap1, weakMap2);
// 通过,因为无法比较条目。

// 失败,因为 weakMap3 有一个 weakMap1 不包含的属性:
assert.deepStrictEqual(weakMap1, weakMap3);
// AssertionError: Input A expected to strictly deep-equal input B:
// + expected - actual
//   WeakMap {
// -   [items unknown]
// +   [items unknown],
// +   unequal: true
//   }

如果值不相等,则抛出 AssertionError,并将 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则会分配默认错误消息。 如果 message 参数是 Error 的实例,那么它将被抛出而不是 AssertionError

assert.doesNotReject(asyncFn[, error][, message])#

中英对照提交修改

等待 asyncFn Promise,或者,如果 asyncFn 是一个函数,则立即调用该函数并等待返回的 Promise 完成。 然后它将检查 Promise 是否被拒绝。

如果 asyncFn 是一个函数并且它同步抛出一个错误,则 assert.doesNotReject() 将返回一个带有该错误的被拒绝的 Promise。 如果函数未返回 Promise,则 assert.doesNotReject() 将返回一个被拒绝的 Promise,其中包含 ERR_INVALID_RETURN_VALUE 错误。 在这两种情况下都会跳过错误处理函数。

使用 assert.doesNotReject() 实际上没有用处,因为捕获拒绝然后再次拒绝它几乎没有什么好处。 应该考虑在不应拒绝的特定代码路径旁边添加注释,并尽可能保留错误消息。

如果指定,则 error 可以是 ClassRegExp 或验证函数。 有关更多详细信息,请参见 assert.throws()

除了等待的异步性质之外,完成行为与 assert.doesNotThrow() 完全相同。

(async () => {
  await assert.doesNotReject(
    async () => {
      throw new TypeError('错误值');
    },
    SyntaxError
  );
})();
assert.doesNotReject(Promise.reject(new TypeError('错误值')))
  .then(() => {
    // ...
  });

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

中英对照提交修改

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

使用 assert.doesNotThrow() 实际上没有用处,因为捕获错误然后重新抛出它没有任何好处。 应该考虑在不应抛出错误的特定代码路径旁边添加注释,并尽可能保留错误消息。

当调用 assert.doesNotThrow() 时,它将立即调用 fn 函数。

如果抛出错误并且它与 error 参数指定的类型相同,则抛出 AssertionError。 如果错误的类型不同,或者 error 参数未定义,则错误将传播回调用方。

如果指定,则 error 可以是 ClassRegExp 或验证函数。 有关更多详细信息,请参见 assert.throws()

例如,以下示例将抛出 TypeError,因为断言中没有匹配的错误类型:

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

以下示例将导致 AssertionError,并显示消息 'Got unwanted exception...':

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

如果抛出 AssertionError 并为 message 参数提供了值,则 message 的值将附加到 AssertionError 消息:

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

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

暂无中英对照

Strict mode

An alias of assert.strictEqual().

Legacy mode

稳定性: 0 - 废弃: 改为使用 assert.strictEqual()

Tests shallow, coercive equality between the actual and expected parameters using the Abstract Equality Comparison ( == ).

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 } }

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

assert.fail([message])#

中英对照提交修改

使用提供的错误消息或默认错误消息抛出 AssertionError。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError

const assert = require('assert').strict;

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

assert.fail('失败');
// AssertionError [ERR_ASSERTION]: 失败

assert.fail(new TypeError('需要数组'));
// TypeError: 需要数组

使用带有两个以上参数的 assert.fail() 是可能的,但已弃用。 请参阅下文了解更多详情。

assert.fail(actual, expected[, message[, operator[, stackStartFn]]])#

暂无中英对照

稳定性: 0 - 废弃: 改为使用 assert.fail([message]) 或 other assert functions 。

If message is falsy, the error message is set as the values of actual and expected separated by the provided operator. If just the two actual and expected arguments are provided, operator will default to '!='. If message is provided as third argument it will be used as the error message and the other arguments will be stored as properties on the thrown object. If stackStartFn is provided, all stack frames above that function will be removed from stacktrace (see Error.captureStackTrace). If no arguments are given, the default message Failed will be used.

const assert = require('assert').strict;

assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'

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

assert.fail(1, 2, new TypeError('need array'));
// TypeError: need array

In the last three cases actual, expected, and operator have no influence on the error message.

Example use of stackStartFn for truncating the exception's stacktrace:

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 不为 undefinednull,则抛出 value。 在回调中测试 error 参数时,这很有用。 堆栈跟踪包含传递给 ifError() 的错误的所有帧,包括 ifError() 本身的潜在新帧。

const assert = require('assert').strict;

assert.ifError(null);
// 通过。
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('错误');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: '错误'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error

// 创建一些随机错误帧。
let err;
(function errorFrame() {
  err = new Error('测试错误');
})();

(function ifErrorFrame() {
  assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 测试错误
//     at ifErrorFrame
//     at errorFrame

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

暂无中英对照

Strict mode

An alias of assert.notDeepStrictEqual().

Legacy mode

稳定性: 0 - 废弃: 改为使用 assert.notDeepStrictEqual()

Tests for any deep inequality. Opposite of 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

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

assert.notDeepEqual(obj1, obj4);
// OK

If the values are deeply equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

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

中英对照提交修改

测试深度严格的不平等。 与 assert.deepStrictEqual() 相反。

const assert = require('assert').strict;

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

如果值深度且严格相等,则抛出 AssertionError,并将 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则会分配默认错误消息。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError

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

暂无中英对照

Strict mode

An alias of assert.notStrictEqual().

Legacy mode

稳定性: 0 - 废弃: 改为使用 assert.notStrictEqual()

Tests shallow, coercive inequality with the Abstract Equality Comparison ( != ).

const assert = require('assert');

assert.notEqual(1, 2);
// OK

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

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

If the values are equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

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

中英对照提交修改

测试 actual 参数和 expected 参数之间的严格不相等,使用 SameValue比较

const assert = require('assert').strict;

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

assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Identical input passed to notStrictEqual: 1

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

如果值严格相等,则抛出 AssertionError,并将 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则会分配默认错误消息。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError

assert.ok(value[, message])#

中英对照提交修改

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

如果 value 不是真值,则抛出 AssertionError,并将 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则会分配默认错误消息。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError。 如果没有传入任何参数,则将 message 设置为字符串:'No value argument passed to `assert.ok()`'

注意,在 repl 中,错误消息将与文件中抛出的错误消息不同!请参阅下文了解更多详情。

const assert = require('assert').strict;

assert.ok(true);
// OK
assert.ok(1);
// OK

assert.ok();
// AssertionError: No value argument passed to `assert.ok()`

assert.ok(false, '这是假值');
// AssertionError: 这是假值

// 在 repl 中:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true

// 在文件中(例如 test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(false)

assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(0)

// 与使用 `assert()` 相同:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert(0)

assert.rejects(asyncFn[, error][, message])#

中英对照提交修改

等待 asyncFn Promise,或者,如果 asyncFn 是一个函数,则立即调用该函数并等待返回的 Promise 完成。 然后它将检查 Promise 是否被拒绝。

如果 asyncFn 是一个函数并且它同步抛出一个错误,则 assert.rejects() 将返回一个带有该错误的被拒绝的 Promise。 如果函数未返回 Promise,则 assert.rejects() 将返回一个被拒绝的 Promise,其中包含 ERR_INVALID_RETURN_VALUE 错误。 在这两种情况下都会跳过错误处理函数。

除了等待的异步性质之外,完成行为与 assert.throws() 完全相同。

如果指定,则 error 可以是 ClassRegExp、验证函数、将测试每个属性的对象、或者将测试每个属性的错误实例(包括不可枚举的 messagename 属性)。

如果指定 message,则当 asyncFn 无法拒绝时 message 将是 AssertionError 提供的消息。

(async () => {
  await assert.rejects(
    async () => {
      throw new TypeError('错误值');
    },
    {
      name: 'TypeError',
      message: '错误值'
    }
  );
})();
assert.rejects(
  Promise.reject(new Error('错误值')),
  Error
).then(() => {
  // ...
});

注意, error 不能是字符串。 如果提供了一个字符串作为第二个参数,则假定 error 被忽略,而字符串将用于 message。 这可能导致容易错过的错误。 如果考虑使用字符串作为第二个参数,请仔细阅读 assert.throws() 中的示例。

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

中英对照提交修改

测试 actual 参数和 expected 参数之间的严格相等性,使用 SameValue比较

const assert = require('assert').strict;

assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
// + expected - actual
// - 1
// + 2

assert.strictEqual(1, 1);
// OK

assert.strictEqual(1, '1');
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
// + expected - actual
// - 1
// + '1'

如果值不严格相等,则抛出 AssertionError,并将 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则会分配默认错误消息。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError

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

中英对照提交修改

期望 fn 函数抛出错误。

如果指定,则 error 可以是 ClassRegExp、验证函数,每个属性将被测试严格的深度相等的验证对象、或每个属性(包括不可枚举的 messagename 属性)将被测试严格的深度相等的错误实例。 使用对象时,还可以在对字符串属性进行验证时使用正则表达式。 请参阅下面的示例。

如果指定 message,则当 fn 调用无法抛出或错误验证失败时, message 将附加到 AssertionError 提供的消息。

自定义的验证对象/错误实例:

const err = new TypeError('错误值');
err.code = 404;
err.foo = 'bar';
err.info = {
  nested: true,
  baz: 'text'
};
err.reg = /abc/i;

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: '错误值',
    info: {
      nested: true,
      baz: 'text'
    }
    // 注意,将仅测试验证对象上的属性。
    // 使用嵌套对象需要存在所有属性。
    // 否则验证将失败。
  }
);

// 使用正则表达式验证错误属性:
assert.throws(
  () => {
    throw err;
  },
  {
    // `name` 和 `message` 属性是字符串,使用正则表达式将匹配字符串。 
    // 如果失败,则会抛出错误。
    name: /^TypeError$/,
    message: /错误/,
    foo: 'bar',
    info: {
      nested: true,
      // 无法对嵌套属性使用正则表达式!
      baz: 'text'
    },
    // `reg` 属性包含一个正则表达式,
    // 并且只有当验证对象包含相同的正则表达式时,
    // 它才会通过。
    reg: /abc/i
  }
);

// 由于 `message` 和 `name` 属性不同而失败:
assert.throws(
  () => {
    const otherErr = new Error('未找到');
    otherErr.code = 404;
    throw otherErr;
  },
  err // 测试 `message`、 `name` 和 `code`。
);

使用构造函数验证 instanceof:

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

使用 RegExp 验证错误消息:

使用正则表达式在错误对象上运行 .toString,因此也将包含错误名称。

assert.throws(
  () => {
    throw new Error('错误值');
  },
  /^Error: 错误值$/
);

自定义的错误验证函数:

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

注意, error 不能是字符串。 如果提供了一个字符串作为第二个参数,则假定 error 被忽略,而字符串将用于 message。 这可能导致容易错过的错误。 使用与抛出的错误消息相同的消息将导致 ERR_AMBIGUOUS_ARGUMENT 错误。 如果使用字符串作为第二个参数,请仔细阅读下面的示例:

function throwingFirst() {
  throw new Error('错误一');
}
function throwingSecond() {
  throw new Error('错误二');
}
function notThrowing() {}

// 第二个参数是一个字符串,输入函数抛出一个错误。
// 第一种情况不会抛出,因为它与输入函数抛出的错误消息不匹配!
assert.throws(throwingFirst, '错误二');
// 在下一个示例中,传入的消息类似来自错误的消息,
// 并且由于不清楚用户是否打算实际匹配错误消息,
// 因此 Node.js 抛出了 `ERR_AMBIGUOUS_ARGUMENT` 错误。
assert.throws(throwingSecond, '错误二');
// 抛出错误:
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// 该字符串仅在函数未抛出时使用(作为消息):
assert.throws(notThrowing, '错误二');
// AssertionError [ERR_ASSERTION]: Missing expected exception: 错误二

// 如果要匹配错误消息,请执行以下操作:
assert.throws(throwingSecond, /错误二$/);
// 因为错误消息匹配而不抛出。
assert.throws(throwingFirst, /错误二$/);
// 抛出错误:
// Error: 错误一
//     at throwingFirst (repl:2:9)

由于令人困惑的表示法,建议不要使用字符串作为第二个参数。 这可能会导致难以发现的错误。