有时候我们只想看看某个方法是否调用了,探测器最适合做这个,借助它的 API ,可以将某个方法替换成能够进行断言的东西。比如用 Sinon 的方法替身 spy 模拟 db.js 中的 fs.writeFile:
sinon.spy(fs.'writeFile');测试完成后,可以用 fs.writeFile.restore() 复原原来的方法。
在 Mocha 之类的测试库中使用时,应该把这些操作放在 beforeEach 和 afterEach 中,下面是探测器用法的完整例子
// spies.js const sinon = require('sinon'); const Database = require('./db'); const fs = require('fs'); const database = new Database('./sample.json'); // ➊ 替换fs 方法 const fsWriteFileSpy = sinon.spy(fs,'writeFile'); const saveDone = sinon.spy(); database.insert('name','Charles Dickens'); database.save(saveDone); // ➋ 断言 writeFile 只调用一次 sinon.assert.calledOnce(fsWriteFileSpy); // ➌ 恢复原来的方法 fs.writeFile.restore();设置好探测器后➊运行要测试的代码。然后调用 sinon.assert➋确保方法被调用了。恢复原来的方法➌。这项测试中的恢复操作不是必须的,但恢复之前改变的方法是最佳实践。
存根
有时候要控制代码流程,比如在测试错误处理代码时,需要强制执行错误处理分支。可以用前面的例子改写,用存根取代探测器,以便执行 writeFile 的回调函数。注意,我们并不是想调用真正的 writeFile.只是希望能运行那个回调函数。下面的是例子。
// stub.js const sinon = require('sinon'); const Database = require('./db'); const fs = require('fs'); const database = new Database('./sample.json'); // 用自己的函数替代 writeFile const stub = sinon.stub(fs,'writeFile',(file,data,cb)=>{ cb(); }); const saveDone = sinon.spy(); database.insert('name','Charles Dickens'); database.save(saveDone); // 断言 writeFile 被调用了 sinon.assert.calledOnce(stub); // 断言 database.save 的回调被调用了 sinon.assert.calledOnce(saveDone); fs.writeFile.restore();在测试有大量用户提供的函数、回调和 promise 的代码时,把存根和探测器结合起来用是最理想的办法。看过这些单元测试工具后,我们该去探究另一种风格的测试了:功能测试。
功能测试在大多数 Web 项目的开发中,进行功能测试的办法都是按用户指定的需求列表驱动浏览器执行操作,然后检查各种 DOM 变化。比如在做一个内容管理系统时,要对图片库的上传功能做功能测试,也就是上传一张图片,然后检查是不是添加上了,在检查是不是加到了正确的图片列表中。
Node 中做功能测试的工具很多,它们大体上可以分成两类:无头测试和基于浏览器的测试。无头测试基本上都是用 PhantomJS 之类的工具提供一个可以在终端里使用的浏览器环境,也有轻便的一些方案会用 Cheerio 和 JSDOM 这样的库。基于浏览器的测试用 Selenium之类的浏览器自动化工具,通过脚本驱动真正的浏览器。两种测试方式用的底层工具都是一样的,可以根据自己的偏好用 Mocha、Jasmine 甚至Cucumber 驱动 Selenium 测试自己的程序。
Selenium 是基于 Java 的浏览器自动化库,在特定语言驱动器的帮助下,可以连接到 Selenium 服务上。用真正的服务器跑测试用例。
https://blog.csdn.net/huilan_same/article/details/51896672
总结编写单元测试需要 Mocha 这样的测试运行器
Node 自带了一个 断言库 assert
还有其他断言库,包括 Chai 和 Should.js
如果不想运行某些代码,比如网络请求,可以用 SinonJS
SinonJS 也可以探测代码,验证某个函数或方法是不是运行了。
通过利用脚本驱动真正的浏览器,可以用 Selenium 编写浏览器测试