QUnit
QUnit官网
对于任何节点.js项目进行简单、零配置设置,对于基于浏览器的项目设置最小配置。
在测试目录中创建文件,并编写以下文件:test/add.js
const add = require('../add.js');
QUnit.module('add');
QUnit.test('add two numbers', assert => {
assert.equal(add(1, 1), 2);
});
定义了"添加"功能的测试套件
现在,您可以通过QUnit CLI运行测试套件。建议您通过 npm 脚本运行命令,该脚本将从本地依赖项中自动找到命令。在package.json文件中定义
{
"scripts": {
"test": "qunit"
}
}
有了单元测试代码,既是一个了解代码的示例,同时还可以自动运行单元测试代码,让代码更健壮
Sinon
Sinon并不是独立的测试框架,它只是在测试中提供spies, stub, mock三种功能, 来模拟和控制资源,需要搭配其他单元测试框架使用。
例如我们常用的测试框架Mocha,Sinon并不能完全替代Mocha的功能。
使用AJAX发送请求给服务端,根据后端返回的数据来渲染页面。后端需要连接数据库,根据获得的数据来执行后续的逻辑代码, 或者其他的依赖。
我们可以用sinon.js来测试
测试替代(test-double)轻松消除测试的复杂度,
测试替代,顾名思义,测试中用到的是真实代码逻辑的替代品。回过头来看Ajax示例,我们不需要设置服务器,而是用Ajax的替代代码,我们把Ajax的逻辑替换成不需要通过请求服务器就返回预先设置好的数据,这听起来有不可思议,但是基本概念很简单。因为JavaScript是动态的,所以我们可以在调用某个方法的时候使用任何函数来替换它。在Sinon中们可以用一个测试逻辑取代任何JavaScript函数,然后让测试复杂的事情变的简单化。
spies
收集有关函数调用的信息。一个spies可以告诉我们调用一个函数的次数、每次调用的参数、返回的值、抛出的错误、是否调用了函数等。
检查被调用次数:
it('should call save once', function() {
var save = sinon.spy(Database, 'save');
setupNewUser({ name: 'test' }, function() { });
save.restore();
sinon.assert.calledOnce(save);
});
stub
拥有spies的所有功能,不是监视某个函数的调用情况,而是完全取代了这个函数。
当使用spies时,原始函数仍然运行,但是当使用stub时,函数将不具有原始的功能,而是替换后的函数。
it('should pass the error into the callback if save fails', function() {
var expectedError = new Error('oops');
var save = sinon.stub(Database, 'save');
save.throws(expectedError);
var callback = sinon.spy();
setupNewUser({ name: 'foo' }, callback);
save.restore();
sinon.assert.calledWith(callback, expectedError);
});
mock
与stub一样都是用来替换指定的函数.
替换掉一个对象中的多个方法,mock,
仅仅是替换对象中的一个函数,stub
it('should pass object with correct values to save only once', function() {
var info = { name: 'test' };
var expectedUser = {
name: info.name,
nameLowercase: info.name.toLowerCase()
};
var database = sinon.mock(Database);
database.expects('save').once().withArgs(expectedUser);
setupNewUser(info, function() { });
database.verify();
database.restore();
});
Mock.js
以下内容学习参看了这里
前端开发中拦截Ajax请求再生成随机数据响应的工具.可以用来模拟服务器响应. 基本覆盖常用的接口数据类型.
$.ajax({
url: 'http://test.com',
type: 'get',
dataType: 'json'
}).done(function(data, status, xhr) {
console.log(JSON.stringify(data, null, 4));
});
var obj = {'aa':'11', 'bb':'22', 'cc':'33', 'dd':'44'};
// Mock响应模板
//数据响应
Mock.mock('http://test.com', {
"user|1-3": [{ // 随机生成1到3个数组元素
'name': '@cname', // 中文名称
'id|+1': 88, // 属性值自动加 1,初始值为88
'age|18-28': 0, // 18至28以内随机整数, 0只是用来确定类型
'birthday': '@date("yyyy-MM-dd")', // 日期
'city': '@city(true)', // 中国城市
'fromObj|2': obj, // 从obj对象中随机获取2个属性
'fromObj2|1-3': obj, // 从obj对象中随机获取1至3个属性
'brother|1': ['jack', 'jim'], // 随机选取 1 个元素
'sister|+1': ['jack', 'jim', 'lily'], // array中顺序选取元素作为结果
'friends|2': ['jack', 'jim'] // 重复2次属性值生成一个新数组
},{
'gf': '@cname'
}]
});
//或者方法响应
Mock.mock('http://test.com', 'get', function() {
return Mock.mock({
"user|1-3": [{
'name': '@cname',
'id': 88
}
]
});
});