面向急切程序员的 JavaScript(ES2022 版)
请支持本书:购买捐赠
(广告,请不要屏蔽。)

10 测验和练习入门



在大多数章节中,都有测验和练习。这些是付费功能,但提供了全面的预览。本章介绍如何开始使用它们。

10.1 测验

安装

运行测验应用程序

10.2 练习

10.2.1 安装练习

要安装练习

10.2.2 运行练习

10.3 JavaScript 中的单元测试

本书中的所有练习都是通过测试框架 Mocha 运行的测试。本节简要介绍一下。

10.3.1 典型的测试

典型的测试代码分为两部分

以以下两个文件为例

10.3.1.1 第 1 部分:代码

代码本身位于 id.mjs

export function id(x) {
  return x;
}

这里的关键是:我们要测试的所有内容都必须导出。否则,测试代码将无法访问它。

10.3.1.2 第 2 部分:测试

  不要担心测试的确切细节

您无需担心测试的确切细节:它们始终为您实现。因此,您只需要阅读它们,而无需编写它们。

代码的测试位于 id_test.mjs

// npm t demos/quizzes-exercises/id_test.mjs
suite('id_test.mjs');

import * as assert from 'assert/strict'; // (A)
import {id} from './id.mjs'; // (B)

test('My test', () => { // (C)
  assert.equal(id('abc'), 'abc'); // (D)
});

此测试文件的核心是 D 行 – 断言assert.equal() 指定 id('abc') 的预期结果为 'abc'

至于其他几行

要运行测试,我们在命令行中执行以下操作

npm t demos/quizzes-exercises/id_test.mjs

ttest 的缩写。也就是说,此命令的长版本是

npm test demos/quizzes-exercises/id_test.mjs

  练习:您的第一个练习

以下练习让您初步了解练习是什么样的

10.3.2 Mocha 中的异步测试

  阅读

您可能希望推迟阅读本节,直到您阅读有关异步编程的章节。

为异步代码编写测试需要额外的工作:测试稍后会收到其结果,并且必须向 Mocha 发出信号,表明它在返回时尚未完成。以下小节将研究三种实现此目的的方法。

10.3.2.1 通过回调实现异步

如果我们传递给 test() 的回调有一个参数(例如,done),则 Mocha 将切换到基于回调的异步。当我们完成异步工作时,我们必须调用 done

test('divideCallback', (done) => {
  divideCallback(8, 4, (error, result) => {
    if (error) {
      done(error);
    } else {
      assert.strictEqual(result, 2);
      done();
    }
  });
});

这就是 divideCallback() 的样子

function divideCallback(x, y, callback) {
  if (y === 0) {
    callback(new Error('Division by zero'));
  } else {
    callback(null, x / y);
  }
}
10.3.2.2 通过 Promise 实现异步

如果测试返回 Promise,则 Mocha 将切换到基于 Promise 的异步。如果 Promise 已完成,则认为测试成功;如果 Promise 被拒绝或结算时间超过超时时间,则认为测试失败。

test('dividePromise 1', () => {
  return dividePromise(8, 4)
  .then(result => {
    assert.strictEqual(result, 2);
  });
});

dividePromise() 的实现如下

function dividePromise(x, y) {
  return new Promise((resolve, reject) => {
    if (y === 0) {
      reject(new Error('Division by zero'));
    } else {
      resolve(x / y);
    }
  });
}
10.3.2.3 异步函数作为测试“主体”

异步函数始终返回 Promise。因此,异步函数是实现异步测试的便捷方法。以下代码等效于上一个示例。

test('dividePromise 2', async () => {
  const result = await dividePromise(8, 4);
  assert.strictEqual(result, 2);
  // No explicit return necessary!
});

我们不需要显式返回任何内容:隐式返回的 undefined 用于完成此异步函数返回的 Promise。如果测试代码抛出异常,则异步函数将负责拒绝返回的 Promise。