一、概述
背景
为了进步集体根底能力,学习优良我的项目的设计和代码编写形式,因而学习should.js的源码并进行剖析
什么是should.js
should is an expressive, readable, framework-agnostic assertion library.should.js是一个表现力强、可读性强、与框架无关的断言库。Node.js自带的断言库Assert,10 多个断言测试的函数,然而性能无限,而should.js能够让测试更加敌对,因而个别前端的单元测试会引入should.js。
二、应用办法
示例
var should = require('should');var user = { name: 'tj' , pets: ['tobi', 'loki', 'jane', 'bandit']};user.should.have.property('name', 'tj');user.should.have.property('pets').with.lengthOf(4);// if the object was created with Object.create(null)// then it doesn't inherit `Object` and have the `should` getter// so you can do:should(user).have.property('name', 'tj');should(true).ok;someAsyncTask(foo, function(err, result){ should.not.exist(err); should.exist(result); result.bar.should.equal(foo);});
应用办法
1、装置
$ npm install should --save-dev
2、应用
var should = require('should');(5).should.be.exactly(5).and.be.a.Number;
三、我的项目构造介绍
我的项目目录
四、源码剖析
index.js
我的项目入口文件,导出node.js
/lib/node.js
var should = require('./should');should .use(require('./ext/assert')) .use(require('./ext/chain')) .use(require('./ext/bool')) .use(require('./ext/number')) .use(require('./ext/eql')) .use(require('./ext/type')) .use(require('./ext/string')) .use(require('./ext/property')) .use(require('./ext/http')) .use(require('./ext/error')) .use(require('./ext/match')) .use(require('./ext/deprecated')); module.exports = should;
引入should.js,而后use办法引入ext文件夹下的扩大办法,便于在测试过程中应用引入的扩大办法。最初导出should。上面咱们先介绍should。
/lib/should.js
/** * Our function should * @param obj * @returns {Assertion} */var should = function(obj) { return new Assertion(util.isWrapperType(obj) ? obj.valueOf(): obj);};/** * Initialize a new `Assertion` with the given _obj_. * * @param {*} obj * @api private */var Assertion = should.Assertion = function Assertion(obj) { this.obj = obj;};...exports = module.exports = should;
should办法返回一个新的Assertion实例,而Assertion断言函数通过传递的obj参数初始化,并在Assertion的原型上定义assert、getMessage、copy、copyIfMissing办法。
接下来定义扩大断言函数的办法:add、alias,它应用了一些逻辑只定义必定的断言和否定的断言自身的规定。所有的动作都产生在子文本中,这种办法思考的是否定。咱们能够增加一些不依赖于断言状态的修饰符。
通过util为should定义断言谬误、format和use办法,最初将should导出,便于前端进行单元测试时通过require将其引入。其中uti文件中定义了我的项目中用到的一些函数,例如判断参数是否是字符串、将b对象属性复制到a对象并返回a对象的merge办法等。
/lib/ext/assert.js
将assert裸露给should,通过util文件中的merge办法将asset中的办法定义在should上,这样在应用的过程中不用应用require()的办法再将asset模块引入。
为should定义exist办法,用于判断传入的第一个参数是否是null,同时在第一个参数是null时抛出谬误显示第二个参数给定的信息。should.not.exist办法则定义当传入的第一个参数不是null时报错。
/lib/ext/chain.js
module.exports = function(should, Assertion) { function addLink(name) { Object.defineProperty(Assertion.prototype, name, { get: function() { return this; } }); } ['an', 'of', 'a', 'and', 'be', 'have', 'with', 'is', 'which', 'the'].forEach(addLink);};
对'an', 'of', 'a', 'and', 'be', 'have', 'with', 'is', 'which', 'the'词语通过addLink办法定义到Assert原型上,使得Assertion也蕴含这些属性,并且返回Assertion对象自身,实现should的链式调用。
源码学习小结
- should.js的文件结构设计正当,例如将should的扩大办法对立放到ext文件夹上面,并且依据性能独自寄存到文件中,这样不仅构造清晰,并且模块化的形式进步代码的复用性,也加强了我的项目的扩展性
- 我的项目通过chain.js文件中的办法实现了Assertion的链式调用
五、总结
should.js我的项目构造十分清晰,尽管和之前学习的axios、promise等我的项目相比,代码量稍多,然而依据我的项目构造浏览起来也不会存在特地大的难度。should.js十分语义化,感觉像是应用英文写自然语言一样写测试,上手容易并且容易浏览,举荐应用should.js进行前端单元测试。