zz from:http://keenwon.com/1223.html
模拟Timeout
Jasmine Clock 可以用来测试setTimeout
和setInterval
的回调操作。它使回调函数同步执行,当Clock的时间超过timer的时间,回调函数会被触发一次。这使依赖于时间的代码更加易于测试。
Jasmine Clock使用jasmine.clock().install
在需要调用timer函数的spec和suite中初始化。在执行完测试的时候,一定要卸载Clock来还原timer函数。使用jasmine.clock().tick
设置时间以使注册的回调触发。
describe("Jasmine Clock 测试", function() { var timerCallback; beforeEach(function() { timerCallback = jasmine.createSpy("timerCallback"); jasmine.clock().install(); }); afterEach(function() { jasmine.clock().uninstall(); }); it("同步触发setTimeout", function() { setTimeout(function() { timerCallback(); }, 100); expect(timerCallback).not.toHaveBeenCalled(); jasmine.clock().tick(101); expect(timerCallback).toHaveBeenCalled(); }); it("同步触发setInterval", function() { setInterval(function() { timerCallback(); }, 100); expect(timerCallback).not.toHaveBeenCalled(); jasmine.clock().tick(101); expect(timerCallback.calls.count()).toEqual(1); jasmine.clock().tick(50); expect(timerCallback.calls.count()).toEqual(1); jasmine.clock().tick(50); expect(timerCallback.calls.count()).toEqual(2); }); });
异步支持
Jasmine支持测试需要执行异步操作的specs,调用beforeEach
, it
, 和afterEach
的时候,可以带一个可选的参数done
,当spec执行完成之后需要调用done
来告诉Jasmine异步操作已经完成。默认Jasmine的超时时间是5s,可以通过全局的jasmine.DEFAULT_TIMEOUT_INTERVAL
设置。
describe("Jasmine 异步测试演示", function() { var value; beforeEach(function(done) { setTimeout(function() { value = 0; done(); }, 1); }); it("should support async execution of test preparation and expectations", function(done) { value++; expect(value).toBeGreaterThan(0); done(); }); describe("5秒钟", function() { var originalTimeout; beforeEach(function() { originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; jasmine.DEFAULT_TIMEOUT_INTERVAL = 6000; }); it("takes a long time", function(done) { setTimeout(function() { done(); }, 5000); }); afterEach(function() { jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; }); }); });
在线测试,注意要等5s才有结果。
测试ajax回调
jasmine-ajax插件(https://github.com/pivotal/jasmine-ajax)用来模拟测试ajax。注意这是个单独的文件,需要额外引用。目前感觉这个用处不大(不然不会以插件的形式出现,呵呵),具体就不说了,这是官方文档:http://jasmine.github.io/2.0/ajax.html,下面直接看个例子:
describe("mocking ajax", function() { describe("suite wide usage", function() { beforeEach(function() { jasmine.Ajax.install(); }); afterEach(function() { jasmine.Ajax.uninstall(); }); it("specifying response when you need it", function() { var doneFn = jasmine.createSpy("success"); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(arguments) { if (this.readyState == this.DONE) { doneFn(this.responseText); } }; xhr.open("GET", "/some/cool/url"); xhr.send(); expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url'); expect(doneFn).not.toHaveBeenCalled(); jasmine.Ajax.requests.mostRecent().response({ "status": 200, "contentType": 'text/plain', "responseText": 'awesome response' }); expect(doneFn).toHaveBeenCalledWith('awesome response'); }); it("allows responses to be setup ahead of time", function() { var doneFn = jasmine.createSpy("success"); jasmine.Ajax.stubRequest('/another/url').andReturn({ "responseText": 'immediate response' }); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(arguments) { if (this.readyState == this.DONE) { doneFn(this.responseText); } }; xhr.open("GET", "/another/url"); xhr.send(); expect(doneFn).toHaveBeenCalledWith('immediate response') }); }); it("allows use in a single spec", function() { var doneFn = jasmine.createSpy('success'); jasmine.Ajax.withMock(function() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(arguments) { if (this.readyState == this.DONE) { doneFn(this.responseText); } }; xhr.open("GET", "/some/cool/url"); xhr.send(); expect(doneFn).not.toHaveBeenCalled(); jasmine.Ajax.requests.mostRecent().response({ "status": 200, "responseText": 'in spec response' }); expect(doneFn).toHaveBeenCalledWith('in spec response'); }); }); });