Nodejs实战 —— 测试 Node 程序 (5)

这个 API 看起来更像是英语句子——声明式风格更冗长,但看起来更加通顺。should 换了种风格:给对象添加属性,这样就不用把断言放在 expect 调用里了

const chai = require('chai'); chai.should(); const foo = 'bar'; foo.should.be.a('string'); foo.should.equal('bar');

要用哪个接口取决于项目,如果先写测试,并将其作为项目的文档,详细的 expect 和 should 接口很好用。

Chai 有很多插件,包括一些趁手的工具,比如可以用 promise 写测试代码的 chai-as-promised,以及根据统计方法比较数值的 chai-stats。注意,因为 Chai 是断言库,所以要跟 Mocha 这样的测试运行者配合使用。另一个像 Chai 一样的 BDD 断言库是 Should.js。

Should.js

Should.js 是个断言库,它用类似于 BDD 的风格表示断言,让测试更容易看懂。它的设计初衷是搭配其他测试框架一起用,我们用的例子是编写代码测试一个定制的模块。Should.js 跟其他框架的搭配很容易,因为它只是给 Object.prototype 增加了一个 should属性。这样你就可以写出表达能力更强的断言,比如 user.role.should.equal('admin'),或者 users.should.include('rick')。

比如说,你要编写一个 Node 命令行的小费计算器,在你跟朋友们采用 AA 制付费时,要用它计算每个人该付多少钱。你希望非程序员朋友也能看懂测试计算逻辑的代码,以免他们怀疑你
耍诈。

初始化并安装依赖

npm init -y npm i --save-dev should

新建并编辑 index.js ,放入实现核心功能的代码,具体来说,消费计算器包含四个辅助函数:

addPercentageToEach——按给定的百分比加大数组中的所有数值

sum——计算数组中所有数值的和

percentFormat——将要显示的值变成百分比格式

dollarFormat——将要显示的值变成美元格式

分账时计算小费的逻辑

// index.js // 按百分比加大数组元素汇总的数值 exports.addPercentageToEach = (prices, percentage) => { return prices.map(total => { total = parseFloat(total); return total + (total * percentage) }); } // 计算数组中所有数值的和 exports.sum = (prices) => { return prices.reduce((currentSum, currentValue) => { return parseFloat(currentSum) + parseFloat(currentValue); }) } // 将要显示的值变成百分比格式 exports.percentFormat = (percentage) => { return parseFloat(percentage) * 100 + '%'; } //将要显示的值变成美元格式 exports.dollarFormat = (number) => { return `$${parseFloat(number).toFixed(2)}`; }

分账时测试计算小费的逻辑

// test/tips.js const tips = require('..'); const should = require('should'); const tax = 0.12; const tip = 0.15; const prices = [10, 20]; const pricesWithTipAndTax = tips.addPercentageToEach(prices, tip + tax); pricesWithTipAndTax[0].should.equal(12.7); pricesWithTipAndTax[1].should.equal(25.4); const totalAmount = tips.sum(pricesWithTipAndTax).toFixed(2); totalAmount.should.equal('38.10'); const totalAmountAsCurrency = tips.dollarFormat(totalAmount); totalAmountAsCurrency.should.equal('$38.10'); const tipAsPercent = tips.percentFormat(tip); tipAsPercent.should.equal('15%');

修改 package.json 中的脚本

"scripts": { "test": "node test/tips.js" }

运行脚本,npm test 如果一切正常,不会输出什么。因为断言没有抛出错误。

Should.js 支持很多种断言,从使用正则表达式的到检查对象属性的全都有,其可以对程序生成的数据和对象进行全面的检查。处理断言库,测试时还经常要用到探测器、存根和模拟对象。

Sinon.JS 的探测器和存根

模拟对象和存根库是测试工具箱里的工具。我们写单元测试是为了把系统的各个组成部分隔离单独测试,但有时候这很难做到。比如测试图片缩放的代码时,如果不想读写真正的图片文件,该怎么写测试代码,代码中不应该有避开文件系统读写的特殊测试分支,因为那样就不是真正的测试了。在这种情况下,需要创建文件系统的功能的存根。可以用存根来代替尚未准备好的依赖项,这有助于实现真正的 TDD。

下面介绍如何 用 SinonJS 编写测试探测器、存根和模拟对象。

初始化,安装依赖

npm init -y npm i --save-dev sinon

接着创建要测试的样例文件,这个例子里用了一个简单的 JSON 键/值数据库,创建一个文件系统 API 的存根,这样就不用在文件系统里创建真正的文件了。我们也可以像下面一样只测试数据库代码,避免处理文件的代码

// db.js const fs = require('fs'); class Database { constructor(filename) { this.filename = filename; this.data = {}; } save(cb) { fs.writeFile(this.filename, JSON.stringify(this.data), cb); } insert(key, value) { this.data[key] = value; } } module.exports = Database;

探测器

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxjzz.html