Sinon.js理解测试理念spy,stub,mock
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Sinon.js理解测试理念spy,stub,mock Sinon.js是个测试辅助工具,在为Node程序写测试时可能可以派
上用场。
个概念都是测试所用到的手段。
Sinon.js就提供了相应的工具来实现这三种测试手段。
if you wouldn’t add an assertion for some specific call, don’t mock it. Use a stub instead. In general you should never have more than one mock (possibly with several expectations) in a single test.
spy
spy的作用在于可以监视一个函数被调用的情况。
spy相当于给我们感兴趣的函数加了一层wrapper,于是记录下了这个函数被调用过几次,每次传入的参数是什么以及每次返回的结果是什么,或是抛出了怎样的异常。
var sinon = require("sinon");
...
sinon.spy(crawler, "launch"); // 监视unch,这是个f unction
... // 对unch进行调用
unch.callCount > 1; // 该函数的调用次数
unch.withArgs("...").calledOnce; // 该函数是否以...参数调用过一次
unch.restore(); // 消除监视
stub
测试中有可能遇到这样的情形:测试函数f1,f1依赖于函数f2,我们需要测试f1在f2的不同表现之下有怎样的表现。
但是让f2有不同的表现可能会很不容易,有可能需要复杂的配置或是精巧的捏造,或是f2出现某种表现的几率很小等等。
这时stub就可派上用场,stub 就是人为设定的f2的替代品。
我们可以设定stub在怎样的输入下有怎样特定的表现,从而不再阻碍对f1的测试。
var sinon = require("sinon");
var stub = sinon.stub(); // 创建一个stub
var stub = sinon.stub(ab, "f"); // 将ab.f替换成一个stub,使用完毕后需要调用stub.restore()或ab.f.restore()来复原
var stub = sinon.stub(ab, "f", function(...) {...}); // 将ab.f替换成指定的函数
stub.returns(10);
stub(); // stub()总是返回10
stub.throws("...");
stub(); // stub()总是抛出"..."
stub.withArgs(1).returns(10);
stub(1); // stub(1)会返回10
stub.restore();
在Sinon.js中,stub本身也是个spy,所以可以在stub上调用之前提到的 .callCount 等查看函数调用情况。
mock
mock在Sinon.js中用于对一个object的活动进行监视。
一个object被mock以后,就可以设定我们对这个object有怎样的预期。
这里的预期例如:某方法被调用了多少次(或至少至多多少次)、某
方法一定没被调用、某方法被输入怎样的参数来调用、等等。
可以看出mock对一个object的监视类似于spy对一个函数的监视。
两者的关键区别在于使用场景,spy客观地监视了一个函数的表现,对这个函数的调用都真正执行了。
而mock出的object收到了数据或是调用并没有真正执行,一切针对mock的调用都是假的。
所以mock可以用来测试具有side effect的函数,这里的side effect泛指和外部对象有数据交互或者是调用,比如调用外部对象的方法、向server发送数据、和UI对象有交互、写日志等等。
var sinon = require("sinon");
var obj = {
...
};
var mock = sinon.mock(obj);
mock.expect("f").atLeast(2).withArgs(10); // obj.f(10)调用至少出现过2次
...
mock.verify(); // 测试此时的obj是否满足上面的mock设定条件
mock.restore();
其他问题
•Sinon.js提供了模拟时间流逝的功能,但似乎并不好用。
对于定时事件的触发会产生怎样的影响,还是先写点测试代码看清楚结果再用为好。
•Sinon.js对Ajax call相关的测试也提供了模拟功能。