Sinon是用来辅助进行前端测试的,在代码需要与其他系统或者函数对接时,它可以模拟这些场景,从而使测试的时候不再依赖这些场景。简单的说,Sinon 允许替换代码中复杂的部分,以此来简化测试代码。
例如:在进行Ajax请求时,不再需要设置服务器,而是用Ajax的替代代码,把Ajax的逻辑替换成不需要通过请求服务器就返回预先设置好的数据。
文档地址:https://sinonjs.org/
npm install --save-dev sinon
var sinon = require('sinon');
Sinon有主要有三个方法辅助进行测试:spy、stub、mock。
spy:监视函数的调用情况。sinon 对监视的函数进行 wrap 包装,因此可以通过它清楚的知道,该函数被调用的次数,传入的参数、返回的结果,甚至是抛出的异常情况。
spy的监听不会影响函数本身的正常调用。
sinon.spy() 函数返回一个 Spy 对象,该对象可以像函数一样被调用,它记录每次被调用的信息。Spy 对象包含很多属性:
// 配合 jest 使用
const sinon = require('sinon');
const testObj = {
'fun': function() {
console.log('I am a function');
}
}
// 监视 testObj.fun
const myspy = sinon.spy(testObj, 'fun');
// // 使用 myspy() 或 testObj.fun() 调用
testObj.fun();
// 测试该函数被调用过一次
test('test', ()=>{
expect(myspy.callCount).toBe(1);
})
// 使用完毕后需要调用myspy.restore() 或 testObj.fun.restore() 复原
myspy.restore();
stub:替换对象的函数行为。在运行时用 stub 替换真正代码,忽略调用代码的原有实现。目的是用一个简单一点的行为替换一个复杂的行为,从而独立地测试代码的某一部分。
例如:一个方法可能依赖另一个方法的执行,而后者对我们来说是透明的。好的做法是使用stub 对它进行隔离替换。这样就实现了更准确的单元测试。
// 配合 jest 使用
const sinon = require('sinon');
const testObj = {
'fun' : function (arg) {}
}
// // 将 testObj.fun 替换成一个stub,
const mystub = sinon.stub(testObj, 'fun');
// 使用 mystub() 或 testObj.fun() 调用
mystub();
// 测试该函数被调用过一次
test('test', ()=>{
expect(mystub.callCount).toBe(1);
})
// 使用完毕后需要调用stub.restore() 或 testObj.fun.restore() 复原
mystub.restore();
还可以替换为指定的函数。
// 配合 jest 使用
const sinon = require('sinon');
const testObj = {
'fun' : function (arg) {
console.log('我是原函数');
}
}
// // 将 testObj.fun 替换成一个stub,
const mystub = sinon.stub(testObj, 'fun').callsFake( (arg) => {
console.log('我是替换函数');
};
// 使用 mystub() 或 testObj.fun() 调用
mystub();
// 测试该函数被调用过一次
test('test', ()=>{
expect(mystub.callCount).toBe(1);
})
// 使用完毕后需要调用stub.restore() 或 testObj.fun.restore() 复原
mystub.restore();
最终将不会打印"我是原函数",而是打印出来"我是替换函数"。
mock:替换整个对象。
mock与stub一样,在监听后,原有函数内容将不会执行。
stub是对对象中单个函数的监听和拦截,mock是对多个。
// 配合 jest 使用
const sinon = require('sinon');
var testObj = {
'fun': function (arg) {}
};
var mock = sinon.mock(testObj);
// 使用 testObj.fun() 调用
testObj.fun(10);
// 测试 obj.fun(10) 至少被调用过 1 次
test('test', () => {
mock.expects('fun').atLeast(1).atMost(5).withArgs(10);
});
// 使用完毕后需要调用stub.restore() 复原
mock.restore();