网络埋伏纪事

如何用Mocha测试JavaScript - 第2部分

网络埋伏纪事 · 2017-06-15翻译 · 466阅读 原文链接

昨天我们学习了Mocha的基础知识。今天,我们会把Mocha整合到一个项目中,这样就可以看到它是如何实际工作的。

这个教程要讲什么?

本教程将提供如何使用Mocha进行测试的小型真实示例。到教程结束时,我们将成功使用Mocha测试现有的JS文件。在读本教程之前,应该先了解Mocha是什么,如何分组测试以及如何使用断言库。如果需要复习,请参阅我的第一篇Mocha教程


项目设置

上一个教程中我们已经安装了Mocha。如果还没有的话,请通过执行$ npm install -g mocha全局安装好Mocha。

接下来,我们要创建一个名为temperature的项目目录。在temperature目录中,我们将创建一个app.js文件,以及一个名为 test 的文件夹。在test文件夹中,创建一个名为test.js的文件。最后,通过运行npm init初始化项目。在项目初始化期间,最重要的问题是 'test command:',回答 'mocha' 就可。这样我们只需键入 npm test 就可以运行Mocha。

搞定后,应该有类似如下的文件结构:

temperature
|-- app.js
|-- package.json
|-- test
   |-- test.js

package.json文件还应包含以下json:

"scripts": {
  "test": "mocha"
},

有了上面所有东西后,我们就可以开始了!

我们在测试什么?

我们将在本教程中测试我们的app.js文件。为了加快进程,我已经写好了app.js的内容。继续,将下面的代码复制到app.js中:

cToF = function(celsius) {
  if(!Number.isInteger(celsius)) return undefined;
  return celsius * 9 / 5 + 32;
}

fToC = function(fahrenheit) {
  if(!Number.isInteger(fahrenheit)) return undefined;
  return (fahrenheit - 32) * 5 / 9;
}

我们的app.js只有九行代码,由两个函数组成:

  • cToF()- 是将摄氏温度转换为华氏温度的函数。它有一个参数,即摄氏温度,并返回对应的华氏温度。

  • fToC() - 是相反的函数。它将华氏温度转为摄氏wen d。它的一个参数是华氏温度,并返回摄氏温度。

  • 这两个函数最初都要检测确保它们被传递进来的参数是一个整数。如果不是整数(字符串、空白、undefinedNaN等),则返回undefined,函数短路。

设置测试

我们将测试以确保这些函数正常运行。这是我们的test.js文件采用的结构:

  1. 一个名为Temperature Conversion的测试组

  2. 在该测试组中,还有其它两个测试组,一个命名为cToF,一个命名为fToC

  3. 每个测试组将有三个测试用例:两个数字和一个非整数测试。

测试组

首先,我们用describe()设置两个测试组:

var assert = require('assert');
describe('Temperature Conversion', function() {
  describe('cToF', function() {
    // tests here
  });
  describe('fToC', function() {
    // tests here
  });
});

上面,我们有两个嵌套的测试组,两个指定函数的describe块在外部Temperature Conversiondescribe块内。现在有了基本的结构,我们就可以给每个内部测试组添加三个it()测试用例。

添加测试用例

三个测试用例都将使用内置的assert断言库。因为要测试相等性,所以我们要用assert.equal(actual,expected);

对于第一个测试,我们将测试一个应该保持不变的数字。如果你不知道的话,华氏温度和摄氏温度在零下40度是相等的。下面我们设置这个测试,以确保我们的函数正确处理数学:

it('should convert -40 celsius to -40 fahrenheit', function() {
   assert.equal(-40, cToF(-40));
});

很棒!我们断言,一旦我们通过函数cToF转换数字-40,结果值也应等于-40

对于下一个测试,我们要看一下水的凝固点。我们想确保0摄氏度等于32华氏度。

it('should convert 0 celsius to 32 fahrenheit', function() {
  assert.equal(32, cToF(0));
});

一切都和第一个测试一样,除了我们将数字0传递到函数中,并期望结果等于32

对于最后一个测试,我们将测试一个空白字符串,并确保函数返回undefined

it('should return undefined if no temperature is input', function(){
  assert.equal(undefined, cToF(''));
});

对于这个测试,我们期望cToF(' ')的结果等于undefined

真棒,我们所有的cToF测试都完成了!现在我们需要为函数fToC做同样的事情。我不会带你去写这些测试 - 你现在应该能自己搞定。如下是它们应该看起来像的样子:

it('should convert -40 fahrenheit to -40 celsius', function() {
  assert.equal(-40, fToC(-40));
});
it('should convert 32 fahrenheit to 0 celsius', function() {
  assert.equal(0, fToC(32));
});
it('should return undefined if no temperature is input', function(){
  assert.equal(undefined, convert.fToC(''));
});

我们完成了...对吧?

真棒,我们的测试设置完了,现在只需用npm test运行即可:

0 passing (20ms)

哦豁。发生了什么事呢?

公开我们的函数

我们从未将我们的函数公开给Mocha。就是说test.js文件没法与app.js文件中的函数进行交互。幸运的是,有很多简单的方法可以做到这一点。

  1. 我们要创建一个名为convert的空对象 let convert = {};

  2. 我们要把每个函数变成新的convert对象上的一个方法,而不是两个不同的函数。

  3. app.js的末尾,我们要用module.exports公开convert对象。如果之前你从没用过module.exports的话,它就是用来告诉JavaScript返回什么对象作为require调用的结果。

下面我们研究一下代码,看看如何用它:

//app.js

let convert = {};

convert.cToF = function(celsius) {
  if(!Number.isInteger(celsius)) return undefined;
  return celsius * 9 / 5 + 32;
}

convert.fToC = function(fahrenheit) {
  if(!Number.isInteger(fahrenheit)) return undefined;
  return (fahrenheit - 32) * 5 / 9;
}

module.exports = convert;

现在要做的只是在test.jsrequire我们的app.js文件,并且把测试中所用的函数名修改为包含convert对象。如下是最终的test.js代码:

//test.js
let convert = require('../app.js')
let assert = require('assert');

describe('Temperature Conversion', function() {
  describe('cToF', function() {
    it('should convert -40 celsius to -40 fahrenheit', function() {
      assert.equal(-40, convert.cToF(-40));
    });
    it('should convert 0 celsius to 32 fahrenheit', function() {
      assert.equal(32, convert.cToF(0));
    });
    it('should return undefined if no temperature is input', function() {
      assert.equal(undefined, convert.cToF(''));
    });
  });
  describe('fToC', function() {
    it('should convert -40 fahrenheit to -40 celsius', function() {
      assert.equal(-40, convert.fToC(-40));
    });
    it('should convert 32 fahrenheit to 0 celsius', function() {
      assert.equal(0, convert.fToC(32));
    });
    it('should return undefined if no temperature is input', function() {
      assert.equal(undefined, convert.fToC('a'));
    });
  });
});

运行测试

这次运行npm test时,一切都按预期工作了!

Temperature Conversion
  cToF
    √ should convert -40 celsius to -40 fahrenheit
    √ should convert 0 celsius to 32 fahrenheit
    √ should return undefined if no temperature is input
  fToC
    √ should convert -40 fahrenheit to -40 celsius
    √ should convert 32 fahrenheit to 0 celsius
    √ should return undefined if no temperature is input

6 passing (34ms)

搞定

干的不错!现在我们在一个单独的文件中测试Mocha。还有更多的东西需要学习 - 去查看文档吧,现在应该有了需要理解它们所需的所有工具了。

相关文章