## 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
}
```
![](https://img.kancloud.cn/ff/a8/ffa8e16628cad59b09c786b836722faa.svg) **测验**
参见[测验应用程序](/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.其余章节在哪里?