使用jasmine作为前端框架进行单元测本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】试,比较坑爹的是当程序中有异步处理,或者【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】模拟、类似异步处理的时候,比较难进行控制【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。。今天就来详细讨论一下clock和set原创内容,盗版必究。未经授权,禁止复制转载。Timeout两种不同的方法在处理不同的【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。情况下的用法。
转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net【未经授权禁止转载】未经授权,禁止复制转载。使用clock模拟时钟快速调用异步操作【访问 www.tangshuang.net 获取更多精彩内容】
【本文首发于唐霜的博客】【作者:唐霜】【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。clock是jasmine里面想象力非常转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。赞的一个功能,它能模拟时钟,快速推进(甚著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。至倒退)程序中的模拟时钟,从而让setT转载请注明出处:www.tangshuang.net【作者:唐霜】imeout、setInterval在你【原创不易,请尊重版权】【本文受版权保护】的模拟时钟里面按照你的想象进行。
【原创不易,请尊重版权】【本文首发于唐霜的博客】【转载请注明来源】比如你写了这样一段代码:本文版权归作者所有,未经授权不得转载。
本文作者:唐霜,转载请注明出处。原创内容,盗版必究。原创内容,盗版必究。setTimeout(() => console.log("ok"), 30*60*1000) // 三十分钟后执行
如果在正常的浏览器时钟中执行这段代码,你【本文受版权保护】【版权所有】唐霜 www.tangshuang.net肯定得等30分钟才能看到控制台输出“OK转载请注明出处:www.tangshuang.net【版权所有,侵权必究】”。但是,通过模拟时间,你能使这个时间在【原创不易,请尊重版权】未经授权,禁止复制转载。模拟状态下进行控制(五维空间的感觉)。
本文作者:唐霜,转载请注明出处。【本文受版权保护】未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。it("test timeout", () => {
let test = 0
jasmine.clock().install() // 安装模拟时钟,会对setTimeout和setInterval进行重写
setTimeout(() => test = 1, 30*60*1000)
console.log(test) // 0
jasmine.clock().tick(30*60*1000)
console.log(test) // 1
})
上面这段代码里面,给了一个test变量,【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】按照setTimeout的设定,test原创内容,盗版必究。本文作者:唐霜,转载请注明出处。要在半个小时之后才会变成1,结果把上面这【原创内容,转载请注明出处】原创内容,盗版必究。段代码放到jasmine的it测试用例中著作权归作者所有,禁止商业用途转载。【本文受版权保护】去执行,秒变1了,为什么?关键就在jasmine.clock().tick(30*60*1000)。在前面执行了著作权归作者所有,禁止商业用途转载。jasmine.clock().install()之后,setTimeout就不是原来的s未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】etTimeout了,执行jasmine.clock().tick(30*60*1000)之后相当于时间已经过了半个小时,所以se【未经授权禁止转载】转载请注明出处:www.tangshuang.nettTimeout里面的回调函数被执行了,未经授权,禁止复制转载。【原创不易,请尊重版权】所以test变成了1,所以下面的test本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。输出为1.
简单的说,clock机制就是重写setT原创内容,盗版必究。未经授权,禁止复制转载。imeout,在调用tick的时候,把模【本文受版权保护】未经授权,禁止复制转载。拟时钟的时间按照自己的意愿推进,如果推进【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net过程中超过了setTimeout设定的时本文作者:唐霜,转载请注明出处。【未经授权禁止转载】间,setTimeout的回调函数就会被【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】执行。为了验证这点,jasmine提供了jasmine.createSpy方法作为监控助手。你可以通过【本文受版权保护】timerCallback.calls.count()来查看回调函数被执行的次数:【原创内容,转载请注明出处】
it("test timeout", () => {
let timerCallback = jasmine.createSpy("timerCallback")
let test = 0
jasmine.clock().install() // 安装模拟时钟,会对setTimeout和setInterval进行重写
setInterval(() => test ++, 30*60*1000)
console.log(test) // 0
jasmine.clock().tick(20*60*1000) // 时间没到,没有调用
console.log(test) // 0
console.log(timerCallback.calls.count()) // 0
jasmine.clock().tick(30*60*1000)
console.log(test) // 1
console.log(timerCallback.calls.count()) // 1,显示出回调函数被执行的次数,可以重复调用tick来看执行的次数
})
那么,jasmine是如何实现clock【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。功能的呢?我们还要去看下源码。这里转载请注明出处:www.tangshuang.net是clock的源码,可以看到,jasmi【关注微信公众号:wwwtangshuangnet】【本文受版权保护】ne确实对setTimeout进行了封装本文作者:唐霜,转载请注明出处。【转载请注明来源】,另外,使用了一个叫delayedFunctionSched著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】ulerFactory的模块,来实现对回调函数列队的存取和调用【原创内容,转载请注明出处】【原创内容,转载请注明出处】。认真阅读这两个模块之后,就可以了解ja著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】smine实现clock的原理。
【原创不易,请尊重版权】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】jasmine中的异步回调测试转载请注明出处:www.tangshuang.net
原创内容,盗版必究。转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】【本文首发于唐霜的博客】从上面你可以看到,clock实际上是想把【原创不易,请尊重版权】【原创不易,请尊重版权】setTimeout等基于时间的几个函数【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】转换为同步执行,也就是说它解决了一个时间【转载请注明来源】未经授权,禁止复制转载。问题。但是,有的时候,程序必须异步执行,原创内容,盗版必究。【未经授权禁止转载】比如ajax,或者异步加载一些数据(pr未经授权,禁止复制转载。【作者:唐霜】omise),甚至setTimeout(著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】fun, 0),这些异步的动作,如果简单【转载请注明来源】未经授权,禁止复制转载。按照我们开发中的思路进行的话,就会出问题本文作者:唐霜,转载请注明出处。原创内容,盗版必究。,测试就会失败。举一个栗子:
【关注微信公众号:wwwtangshuangnet】【作者:唐霜】转载请注明出处:www.tangshuang.netit("test data", () => {
let content = ""
$.get("your url").then(data => content = data)
expect(content).not.toBe("")
})
我们虽然使用了ajaxMock,对jqu本文作者:唐霜,转载请注明出处。【作者:唐霜】ery的ajax请求进行了模拟,但是由于转载请注明出处:www.tangshuang.net【转载请注明来源】使用的是deffered,所以这个请求仍【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。然是模拟的异步操作。当expect执行的未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net时候,$.get的then可能还没有执行原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。,因此可能就会得到错误的测试结果。
【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。【本文首发于唐霜的博客】【原创不易,请尊重版权】【本文首发于唐霜的博客】jasmine解决异步测试的方法非常简单【原创内容,转载请注明出处】【作者:唐霜】,就是在it的回调函数中传入参数作为标记【本文首发于唐霜的博客】【作者:唐霜】,比如把上面的代码改为:
【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】it("test data", done => {
let content = ""
$.get("your url").then(data => {
content = data
expect(content).not.toBe("")
done()
})
})
当done被传入之后,只有调用done时本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。,jasmine才认为这个测试用例结束,未经授权,禁止复制转载。未经授权,禁止复制转载。否则这个测试用例将处于等待状态。
原创内容,盗版必究。【版权所有,侵权必究】
不过有一个点需要注意,就是setTim【转载请注明来源】著作权归作者所有,禁止商业用途转载。eout异步测试的时候,不能和clock未经授权,禁止复制转载。【未经授权禁止转载】一起使用,比如:
beforeEach(() => jasmine.clock().install())it("test async", done => {$.get(...).then(...)setTimeout(() => {expect(...).toBe(...)}, 1000)})afterEach(() => jasmine.clock().uninstall())
上面这段代码会报错!!!原因很简单,因为【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】clock需要通过tick来推进时间,而原创内容,盗版必究。【本文受版权保护】上面代码中时间将永远禁止。
未经授权,禁止复制转载。【转载请注明来源】著作权归作者所有,禁止商业用途转载。既然如此,那加上tick不就好了吗?对不著作权归作者所有,禁止商业用途转载。【转载请注明来源】起,仍然会失败(不报错)。前文已经说明,原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。tick其实是调用回调函数,而立即调用回【版权所有,侵权必究】未经授权,禁止复制转载。调函数,$.get方法请求的数据其实还没著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】有回来,所以你expect中的值是原始值本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。,不会得到正确的结果。所以,如果是使用a【本文首发于唐霜的博客】【转载请注明来源】jax,不要用timeout的方式去ex【作者:唐霜】【版权所有,侵权必究】pect,而是应该写在ajax的回调函数【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。中,采用done作为回调通知。
【本文受版权保护】【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】jasmine提供了一个著作权归作者所有,禁止商业用途转载。ajax的解决方案【原创不易,请尊重版权】,和clock非常像,也是对【转载请注明来源】XMLHttpRequest进行重写,也【转载请注明来源】转载请注明出处:www.tangshuang.net采用jasmine.Ajax.install()这种形式。不过它不是jasmine-co【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】re的内容,而是以插件的形式挂载到jas【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】mine中去。
jasmine1.3供了两个函数,run【作者:唐霜】原创内容,盗版必究。s和waitsFor来实现,但是2.0开【本文首发于唐霜的博客】【作者:唐霜】始使用done的方式异步通知方便的多。
【本文受版权保护】【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】总结本文作者:唐霜,转载请注明出处。
【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【未经授权禁止转载】本文作者:唐霜,转载请注明出处。本文总结了jasmine中clock和异【本文受版权保护】【关注微信公众号:wwwtangshuangnet】步的两个问题。简单的说,clock主要用【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。在“不想等待,直接快进时间”,而异步则主【转载请注明来源】【版权所有,侵权必究】要用在“需要等待”。使用clock不能把【作者:唐霜】【作者:唐霜】它当setTimeout来用,实际上相反转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net,clock是把setTimeout同步【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。执行,是把setTimeout作为其他程【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。序进行的依赖来处理,比如:
本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】【本文首发于唐霜的博客】【未经授权禁止转载】【原创内容,转载请注明出处】setTimeout(() => a = 1, 1000)setTimeout(() => b = a + 2, 200)
上面这段代码,第二个setTimeout著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。依赖于第一个,所以这个时候使用clock【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。快进时间就很爽,但是绝不能把它用在异步操【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】作中,clock无法让ajax的请求变快本文作者:唐霜,转载请注明出处。【未经授权禁止转载】,ajax请求仍然是自己的那个节奏,如果【本文首发于唐霜的博客】【本文受版权保护】你在请求还没回来的时候就直接通过cloc【本文受版权保护】本文版权归作者所有,未经授权不得转载。k去快进时间,得到的只是ajax还没成功【作者:唐霜】【作者:唐霜】时拿到的数据,比如上面提到的那个反例。
【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】2017-02-27 6005 jasmine


