## 8.斷言 API
> 原文: [http://exploringjs.com/impatient-js/ch_assertion-api.html](http://exploringjs.com/impatient-js/ch_assertion-api.html)
>
> 貢獻者:[lq920320](https://github.com/lq920320)
### 8.1. 軟件開發中的斷言
在軟件開發中,*斷言*陳述關于值或代碼片段必須為真的事實。如果不為真,則拋出異常。Node.js 通過其內置模塊`assert`支持斷言。例如:
```js
import {strict as assert} from 'assert';
assert.equal(3 + 5, 8);
```
該斷言表明 3 加 5 的預期結果為 8。`import` 語句建議使用 [`assert`的`strict`版本](https://nodejs.org/api/assert.html#assert_strict_mode)。
### 8.2. 本書中如何使用斷言
在本書中,斷言有兩種用途:在代碼示例中記錄結果以及實現測試驅動的練習。
#### 8.2.1. 通過斷言記錄代碼示例中的結果
在代碼示例中,斷言表達了預期的結果。舉例來說,以下函數:
```js
function id(x) {
return x;
}
```
`id()`返回其參數。我們可以通過斷言來證明它:
```js
assert.equal(id('abc'), 'abc');
```
在示例中,我通常省略導入`assert`的語句。
使用斷言的動機是:
- 您可以精確指定預期的內容。
- 代碼示例可以自動測試,這可以確保它們真正起作用。
#### 8.2.2. 通過斷言實現測試驅動的練習
本書的練習是通過測試框架`mocha`進行測試驅動的。測試內部的檢查是通過`assert`的方法進行的。
以下是此類測試的示例:
```js
// For the exercise, you must implement the function hello().
// The test checks if you have done it properly.
test('First exercise', () => {
assert.equal(hello('world'), 'Hello world!');
assert.equal(hello('Jane'), 'Hello Jane!');
assert.equal(hello('John'), 'Hello John!');
assert.equal(hello(''), 'Hello !');
});
```
有關更多信息,請參閱[關于測驗和練習](/docs/11.md#91測驗)的章節。
### 8.3. 正常比較與深度比較
嚴格的 `equal()`使用`===`來比較值。因此,一個對象只等于它自己——即使另一個對象具有相同的內容(因為`===`不比較對象的內容,只比較它們的唯一標識):
```js
assert.notEqual({foo: 1}, {foo: 1});
```
`deepEqual()`是比較對象的更好選擇:
```js
assert.deepEqual({foo: 1}, {foo: 1});
```
此方法也適用于數組:
```js
assert.notEqual(['a', 'b', 'c'], ['a', 'b', 'c']);
assert.deepEqual(['a', 'b', 'c'], ['a', 'b', 'c']);
```
### 8.4. 快速參考:模塊`assert`
有關完整文檔,請參閱 [Node.js 文檔](https://nodejs.org/api/assert.html)。
#### 8.4.1. 普通相等
- `function equal(actual: any, expected: any, message?: string): void`
`actual === expected`必須是`true`。如果不是,則拋出`AssertionError`。
```js
assert.equal(3+3, 6);
```
- `function notEqual(actual: any, expected: any, message?: string): void`
`actual !== expected`必須是`true`。如果不是,則拋出`AssertionError`。
```js
assert.notEqual(3+3, 22);
```
可選的最后一個參數`message`可用于解釋斷言的內容。如果斷言失敗,則消息用于設置拋出的`AssertionError`。
```js
let e;
try {
const x = 3;
assert.equal(x, 8, 'x must be equal to 8')
} catch (err) {
assert.equal(String(err), 'AssertionError [ERR_ASSERTION]: x must be equal to 8');
}
```
#### 8.4.2. 深度相等
* `function deepEqual(actual: any, expected: any, message?: string): void`
`actual`必須與`expected`完全相同。如果不是,則拋出`AssertionError`。
```js
assert.deepEqual([1,2,3], [1,2,3]);
assert.deepEqual([], []);
// To .equal(), an object is only equal to itself:
assert.notEqual([], []);
```
* `function notDeepEqual(actual: any, expected: any, message?: string): void`
`actual`不得與`expected`深度相等。如果是,則拋出`AssertionError`。
#### 8.4.3. 期望異常
如果你想(或期望)接收異常,你需要`throws()`:這個函數調用它的第一個參數,函數`block`,只有在它拋出異常時才會成功。其他參數可用于指定該異常必須是什么樣的。
- `function throws(block: Function, message?: string): void`
```js
assert.throws(
() => {
null.prop;
}
);
```
- `function throws(block: Function, error: Function, message?: string): void`
```js
assert.throws(
() => {
null.prop;
},
TypeError
);
```
- `function throws(block: Function, error: RegExp, message?: string): void`
```js
assert.throws(
() => {
null.prop;
},
/^TypeError: Cannot read property 'prop' of null$/
);
```
- `function throws(block: Function, error: Object, message?: string): void`
```js
assert.throws(
() => {
null.prop;
},
{
name: 'TypeError',
message: `Cannot read property 'prop' of null`,
}
);
```
#### 8.4.4. 另一個工具函數
- `function fail(message: string | Error): never`
調用時始終拋出`AssertionError`。這有時對單元測試很有用。
```js
try {
functionThatShouldThrow();
assert.fail();
} catch (_) {
// Success
}
```
 **測驗**
參見[測驗應用程序](/docs/11.md#91測驗)。
- I.背景
- 1.關于本書(ES2019 版)
- 2.常見問題:本書
- 3. JavaScript 的歷史和演變
- 4.常見問題:JavaScript
- II.第一步
- 5.概覽
- 6.語法
- 7.在控制臺上打印信息(console.*)
- 8.斷言 API
- 9.測驗和練習入門
- III.變量和值
- 10.變量和賦值
- 11.值
- 12.運算符
- IV.原始值
- 13.非值undefined和null
- 14.布爾值
- 15.數字
- 16. Math
- 17. Unicode - 簡要介紹(高級)
- 18.字符串
- 19.使用模板字面值和標記模板
- 20.符號
- V.控制流和數據流
- 21.控制流語句
- 22.異常處理
- 23.可調用值
- VI.模塊化
- 24.模塊
- 25.單個對象
- 26.原型鏈和類
- 七.集合
- 27.同步迭代
- 28.數組(Array)
- 29.類型化數組:處理二進制數據(高級)
- 30.映射(Map)
- 31. WeakMaps(WeakMap)
- 32.集(Set)
- 33. WeakSets(WeakSet)
- 34.解構
- 35.同步生成器(高級)
- 八.異步
- 36. JavaScript 中的異步編程
- 37.異步編程的 Promise
- 38.異步函數
- IX.更多標準庫
- 39.正則表達式(RegExp)
- 40.日期(Date)
- 41.創建和解析 JSON(JSON)
- 42.其余章節在哪里?