1. 程式人生 > >assert 斷言

assert 斷言

剛開始接觸這塊說不好自己的想法只能借用學習文件來記錄我的學習過程,以後會慢慢加強的。下面是文件的內容:

assert 模組提供了斷言測試的函式,用於測試不變式。

assert.AssertionError 類

Error 的一個子類,表明斷言的失敗。 assert 模組丟擲的所有錯誤都是 AssertionError 類的例項。

new assert.AssertionError(options)

  • options
    • message 如果有值,則錯誤資訊會被設為該值。
    • actual 錯誤例項的 actual 屬性會被設為該值。用於 actual 錯誤輸入,例如使用 assert.strictEqual()。
    • expected 錯誤例項的 expected 屬性會被設為該值。用於 expected 錯誤輸入,例如使用 assert.strictEqual()。
    • operator 錯誤例項的 operator 屬性會被設為該值。用於表明比較時使用的是哪個操作(或觸發錯誤的是哪個斷言函式)。
    • stackStartFn 如果有值,則由提供的函式生成堆疊蹤跡。

所有例項都包含內建的 Error 屬性(message 和 name)以及:

  • actual 被設為實際值,例如使用 assert.strictEqual()。
  • expected 被設為期望值,例如使用 assert.strictEqual()。
  • generatedMessage 表明資訊是否為自動生成的。
  • code 總是被設為 ERR_ASSERTION,表明錯誤是一個斷言錯誤。
  • operator 被設為傳入的運算子的值。
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);
}

assert(value[, message])

  - value <any> 要檢查是否為真的值。
  - message <string> | <Error>

assert.ok() 的別名。

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

- actual <any>
- expected <any>
- message <string> | <Error>

測試實際引數和預期引數之間的深度相等性。將原值與抽象等式比較(==).

只考慮可列舉的“自有”屬性。deepequal()實現不測試物件的[[Prototype]]或可列舉的自己的符號屬性。對於此類檢查,請考慮使用assert.deepStrictEqual()。deepequal()可能會有令人驚訝的結果。下面的示例不會丟擲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

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

如果值不相等,將丟擲AssertionError,其訊息屬性設定為等於訊息引數的值。如果訊息引數未定義,則會分配一個預設錯誤訊息。如果訊息引數是錯誤的例項,那麼它將被丟擲,而不是AssertionError。

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

- actual <any>
- expected <any>
- message <string> | <Error>

測試 actual 引數與 expected 引數是否深度相等。 深度相等意味著子物件中可列舉的自身屬性也會按以下規則遞迴地比較。

比較的詳細說明

  • 原始值運用 SameValue比較法進行比較,使用 Object.is() 函式。
  • 物件的型別標籤應該相同。
  • 物件的原型使用全等運算子比較。
  • 只比較可列舉的自身屬性。
  • Error 的名稱與資訊也會比較,即使不是可列舉的屬性。
  • 可列舉的自身 Symbol 屬性也會比較。
  • 物件封裝器 會同時比較物件與解封裝後的值。
  • Object 屬性的比較是無序的。
  • Map 鍵名與 Set 子項的比較是無序的。
  • 當兩邊的值不相同或遇到迴圈引用時,遞迴會停止。
  • WeakMap 與 WeakSet 的比較不依賴於它們的值。
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 比較法中 0 與 -0 不同:
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
//   }

如果兩個值不相等,則丟擲一個帶有 message 屬性的 AssertionError,其中 message 屬性的值等於傳入的 message 引數的值。 如果 message 引數為 undefined,則賦予預設的錯誤資訊。 如果 message 引數是 Error 的例項,則會丟擲它而不是 AssertionError。

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

- asyncFn <Function> | <Promise>
- error <RegExp> | <Function>
- message <string>

等待asyncFn承諾,或者,如果asyncFn是一個函式,立即呼叫函式並等待返回的承諾完成。然後它會檢查承諾是否被拒絕。

如果asyncFn是一個函式,它會同步丟擲一個錯誤,assert.doesNotReject()會返回一個帶有該錯誤的拒絕承諾。如果函式不返回一個promise, assert.doesNotReject()將返回一個被拒絕的promise,並且返回一個ERR_INVALID_RETURN_VALUE錯誤。在這兩種情況下都跳過了錯誤處理程式。

請注意:使用assert.doesNotReject()實際上是沒有用的,因為捕獲一個拒絕並再次拒絕它幾乎沒有什麼好處。相反,考慮在特定的程式碼路徑旁邊新增一條註釋,該註釋不應該被拒絕,並儘可能保持錯誤訊息的表達性。

如果指定,錯誤可以是類、RegExp或驗證函式。有關詳細資訊,請參閱assert.throw()。

除了等待完成的非同步性質,assert. notthrow()的行為與assert. notthrow()相同。

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

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

- fn <Function>
- error <RegExp> | <Function>
- message <string>

斷言函式fn不會丟擲錯誤。

請注意:使用assert.doesNotThrow()實際上是沒有用的,因為捕獲錯誤並重新丟擲它沒有任何好處。相反,考慮在特定的程式碼路徑旁邊新增一條註釋,該註釋不應該丟擲錯誤訊息,並儘可能保持錯誤訊息的表達性。

當呼叫assert. notthrow()時,它將立即呼叫fn函式。

如果丟擲的錯誤與錯誤引數指定的型別相同,則丟擲AssertionError。如果錯誤屬於另一種型別,或者錯誤引數未定義,則將錯誤傳播回撥用者。

如果指定,錯誤可以是類、RegExp或驗證函式。有關詳細資訊,請參閱assert.throw()。

例如,下面將丟擲TypeError,因為斷言中沒有匹配的錯誤型別:

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError
);

但是,下面的訊息將導致AssertionError,提示“得到不需要的異常…”

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  TypeError
);

如果引發了AssertionError,並且為訊息引數提供了一個值,那麼將向AssertionError訊息追加訊息的值:

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  /Wrong value/,
  'Whoops'
);
// Throws: AssertionError: Got unwanted exception: Whoops

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

- actual <any>
- expected <any>
- message <string> | <Error>

使用抽象平等比較(==)測試實際引數和預期引數之間的淺層強制平等。

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,其訊息屬性設定為等於訊息引數的值。如果訊息引數未定義,則會分配一個預設錯誤訊息。如果訊息引數是錯誤的例項,那麼它將被丟擲,而不是AssertionError。

assert.fail([message])

- message <string> | <Error> 預設為 'Failed'。

丟擲 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]]])

- actual <any>
- expected <any>
- message <string> | <Error>
- operator <string> Default: '!='
- stackStartFn <Function> Default: assert.fail

如果訊息是falsy,則將錯誤訊息設定為實際值和預期值,由提供的操作符分隔。如果只提供了兩個實際的和預期的引數,操作符將預設為’!=’。如果訊息作為第三個引數提供,它將用作錯誤訊息,其他引數將作為丟擲物件上的屬性儲存。如果提供了stackStartFn,那麼該函式上面的所有堆疊幀都將從stacktrace中刪除。如果沒有提供引數,將使用預設訊息Failed。

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

在最後三種情況下,實際的、預期的和操作符對錯誤訊息沒有影響。

例如使用stackStartFn截斷異常的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 <any>

如果 value 不為 undefined 或 null,則丟擲 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])

- actual <any>
- expected <any>
- message <string> | <Error>

測試任何深度的不等式。相反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

如果值完全相等,將丟擲AssertionError,其訊息屬性設定為等於訊息引數的值。如果訊息引數未定義,則會分配一個預設錯誤訊息。如果訊息引數是錯誤的例項,那麼它將被丟擲,而不是AssertionError。

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

- actual <any>
- expected <any>
- message <string> | <Error>

測試 actual 引數與 expected 引數是否不深度全等。 與 assert.deepStrictEqual() 相反。

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

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

如果兩個值深度全等,則丟擲一個帶有 message 屬性的 AssertionError,其中 message 屬性的值等於傳入的 message 引數的值。 如果 message 引數為 undefined,則賦予預設的錯誤資訊。 如果 message 引數是 Error 的例項,則會丟擲它而不是 AssertionError。

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

- actual <any>
- expected <any>
- message <string> | <Error>
const assert = require('assert');

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

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

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

如果值相等,將丟擲AssertionError,其訊息屬性設定為等於訊息引數的值。如果訊息引數未定義,則會分配一個預設錯誤訊息。如果訊息引數是錯誤的例項,那麼它將被丟擲,而不是AssertionError。

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

- actual <any>
- expected <any>
- message <string> | <Error>

使用 SameValue比較法測試 actual 引數與 expected 引數是否不全等。

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');
// 測試通過。

如果兩個值全等,則丟擲一個帶有 message 屬性的 AssertionError,其中 message 屬性的值等於傳入的 message 引數的值。 如果 message 引數為 undefined,則賦予預設的錯誤資訊。 如果 message 引數是 Error 的例項,則會丟擲它而不是 AssertionError。

assert.ok(value[, message])

- value <any>
- message <string> | <Error>

測試 value 是否為真值。 相當於 assert.equal(!!value, true, message)。

如果 value 不為真值,則丟擲一個帶有 message 屬性的 AssertionError,其中 message 屬性的值等於傳入的 message 引數的值。 如果 message 引數為 undefined,則賦予預設的錯誤資訊。 如果 message 引數是 Error 的例項,則會丟擲它而不是 AssertionError。 如果沒有傳入引數,則 message 會被設為字串 'No value argument passed to assert.ok()

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

assert.ok(true);
// 測試通過。
assert.ok(1);
// 測試通過。

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 <Function> | <Promise>
- error <RegExp> | <Function> | <Object> | <Error>
- message <string>

等待asyncFn承諾,或者,如果asyncFn是一個函式,立即呼叫函式並等待返回的承諾完成。然後它會檢查承諾是否被拒絕。

如果asyncFn是一個函式,它同步丟擲一個錯誤,assert.reject()會返回一個帶有該錯誤的拒絕承諾。如果函式不返回一個promise, assert.reject()將返回一個拒絕的promise,並且返回一個ERR_INVALID_RETURN_VALUE錯誤。在這兩種情況下都跳過了錯誤處理程式。

除了等待完成的非同步性質之外,assert.throw()的行為也一樣。

如果指定,錯誤可以是類、RegExp、驗證函式、測試每個屬性的物件或測試每個屬性的錯誤例項(包括不可列舉的訊息和名稱屬性)。

如果指定了,如果asyncFn拒絕,訊息將是AssertionError提供的訊息。

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

注意,錯誤不能是字串。如果提供了一個字串作為第二個引數,則假定忽略了錯誤,該字串將被用於訊息。這會導致容易忽略的錯誤。如果考慮使用字串作為第二個引數,請仔細閱讀assert.throw()中的示例。

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

- actual <any>
- expected <any>
- message <string> | <Error>

使用 SameValue比較法測試 actual 引數與 expected 引數是否全等。

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);
// 測試通過。

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

如果兩個值不全等,則丟擲一個帶有 message 屬性的 AssertionError,其中 message 屬性的值等於傳入的 message 引數的值。 如果 message 引數為 undefined,則賦予預設的錯誤資訊。 如果 message 引數是 Error 的例項,則會丟擲它而不是 AssertionError。

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

- fn <Function>
- error <RegExp> | <Function> | <Object> | <Error>
- message <string>

期望函式fn丟擲一個錯誤。

如果指定,錯誤可以是類、RegExp、驗證函式、驗證物件,其中每個屬性都將被測試為嚴格的深度相等,或者錯誤例項,其中每個屬性都將被測試為嚴格的深度相等,包括不可列舉的訊息和名稱屬性。在使用物件時,在對字串屬性進行驗證時,也可以使用正則表示式。下面是一些例子。

如果指定,如果fn呼叫未能丟擲或錯誤驗證失敗,則會將訊息追加到AssertionError提供的訊息中。

自定義驗證物件/錯誤例項:

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

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
    info: {
      nested: true,
      baz: 'text'
    }
    // Note that only properties on the validation object will be tested for.
    // Using nested objects requires all properties to be present. Otherwise
    // the validation is going to fail.
  }
);

// Using regular expressions to validate error properties:
assert.throws(
  () => {
    throw err;
  },
  {
    // The `name` and `message` properties are strings and using regular
    // expressions on those will match against the string. If they fail, an
    // error is thrown.
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // It is not possible to use regular expressions for nested properties!
      baz: 'text'
    },
    // The `reg` property contains a regular expression and only if the
    // validation object contains an identical regular expression, it is going
    // to pass.
    reg: /abc/i
  }
);

// Fails due to the different `message` and `name` properties:
assert.throws(
  () => {
    const otherErr = new Error('Not found');
    otherErr.code = 404;
    throw otherErr;
  },
  err // This tests for `message`, `name` and `code`.
);

Validate instanceof using constructor:

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  Error
);

使用RegExp驗證錯誤訊息:

使用正則表示式在錯誤物件上執行. tostring,因此還將包含錯誤名稱。

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  /^Error: Wrong value$/
);

自定義錯誤驗證:

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  function(err) {
    if ((err instanceof Error) && /value/.test(err)) {
      return true;
    }
  },
  'unexpected error'
);

注意,錯誤不能是字串。如果提供了一個字串作為第二個引數,則假定忽略了錯誤,該字串將被用於訊息。這會導致容易忽略的錯誤。使用與丟擲錯誤訊息相同的訊息將導致err_ous_argument錯誤。如果考慮使用字串作為第二個引數,請仔細閱讀下面的示例:

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.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js thrown an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// Throws an error:
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// 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 an error:
// Error: First
//     at throwingFirst (repl:2:9)

由於符號混亂,建議不要使用字串作為第二個引數。這可能會導致難以發現的錯誤。