Javascript测试框架Jasmine(五):Spies
来源:互联网 发布:网络推广公司wtg168 编辑:程序博客网 时间:2024/06/06 13:10
zz from: http://keenwon.com/1218.html
Spies是Jasmine里面比较高端的方法,可以用来模拟函数的执行,以达到隔离复杂依赖的效果。例如,你要测试列表的处理是否正确,但是数据是异步请求接口取得的,这时你就可以使用Spies,模拟返回各种不同的数据进行测试。
spy可以保存任何函数的调用记录和输入的参数,spy只能存在于describe和it中,在spec执行完之后销毁。先说两个针对spies的Matcher,toHaveBeenCalled
用来测试函数是否被调用过;toHaveBeenCalledWith
用来测试函数被调用时的参数列表,匹配的话返回true
,看个例子:
- describe("A spy", function() {
- var foo, bar = null;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- }
- };
- spyOn(foo, 'setBar');
- foo.setBar(123);
- foo.setBar(456, 'another param');
- });
- it("tracks that the spy was called", function() {
- expect(foo.setBar).toHaveBeenCalled();
- });
- it("tracks all the arguments of its calls", function() {
- expect(foo.setBar).toHaveBeenCalledWith(123);
- expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
- });
- it("stops all execution on a function", function() {
- expect(bar).toBeNull();
- });
- });
and.callThrough
spy链式调用and.callThrough
后,在获取spy的同时,调用实际的函数,看示例:
- describe("A spy, when configured to call through", function() {
- var foo, bar, fetchedBar;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- },
- getBar: function() {
- return bar;
- }
- };
- spyOn(foo, 'getBar').and.callThrough();
- foo.setBar(123);
- fetchedBar = foo.getBar();
- });
- it("tracks that the spy was called", function() {
- expect(foo.getBar).toHaveBeenCalled();
- });
- it("should not effect other functions", function() {
- expect(bar).toEqual(123);
- });
- it("when called returns the requested value", function() {
- expect(fetchedBar).toEqual(123);
- });
- });
如果不加and.callThrough
的话,最后一个测试中的fetchedBar
,其实只是spyOn
方法的返回值,并不会执行原始的函数,返回123。
and.returnValue
spy链式调用and.returnValue
,返回指定值。
- describe("A spy, when configured to fake a return value", function() {
- var foo, bar, fetchedBar;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- },
- getBar: function() {
- return bar;
- }
- };
- spyOn(foo, "getBar").and.returnValue(745);
- foo.setBar(123);
- fetchedBar = foo.getBar();
- });
- it("tracks that the spy was called", function() {
- expect(foo.getBar).toHaveBeenCalled();
- });
- it("should not effect other functions", function() {
- expect(bar).toEqual(123);
- });
- it("when called returns the requested value", function() {
- expect(fetchedBar).toEqual(745);
- });
- });
and.callFake
spy链式调用and.callFake
,执行指定函数。
- describe("A spy, when configured with an alternate implementation", function() {
- var foo, bar, fetchedBar;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- },
- getBar: function() {
- return bar;
- }
- };
- spyOn(foo, "getBar").and.callFake(function() {
- return 1001;
- });
- foo.setBar(123);
- fetchedBar = foo.getBar();
- });
- it("tracks that the spy was called", function() {
- expect(foo.getBar).toHaveBeenCalled();
- });
- it("should not effect other functions", function() {
- expect(bar).toEqual(123);
- });
- it("when called returns the requested value", function() {
- expect(fetchedBar).toEqual(1001);
- });
- });
and.throwError
spy链式调用and.throwError
,抛出异常:
- describe("A spy, when configured to throw an error", function() {
- var foo, bar;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- }
- };
- spyOn(foo, "setBar").and.throwError("quux");
- });
- it("throws the value", function() {
- expect(function() {
- foo.setBar(123)
- }).toThrowError("quux");
- });
- });
and.stub
spy恢复到原始状态,不执行任何操作。直接看下源码比较好懂 https://github.com/pivotal/jasmine/blob/master/src/core/SpyStrategy.js
- describe("A spy", function() {
- var foo, bar = null;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- }
- };
- spyOn(foo, 'setBar').and.callThrough();
- });
- it("can call through and then stub in the same spec", function() {
- foo.setBar(123);
- expect(bar).toEqual(123);
- foo.setBar.and.stub();
- bar = null;
- foo.setBar(123);
- expect(bar).toBe(null);
- });
- });
jasmine.createSpy
当没有函数可以spy的时候,可以创建一个“基础的”spy,它的背后没有任何实际的操作,例如:
- describe("A spy, when created manually", function() {
- var whatAmI;
- beforeEach(function() {
- whatAmI = jasmine.createSpy('whatAmI');
- whatAmI("I", "am", "a", "spy");
- });
- it("is named, which helps in error reporting", function() {
- expect(whatAmI.and.identity()).toEqual('whatAmI');
- });
- it("tracks that the spy was called", function() {
- expect(whatAmI).toHaveBeenCalled();
- });
- it("tracks its number of calls", function() {
- expect(whatAmI.calls.count()).toEqual(1);
- });
- it("tracks all the arguments of its calls", function() {
- expect(whatAmI).toHaveBeenCalledWith("I", "am", "a", "spy");
- });
- it("allows access to the most recent call", function() {
- expect(whatAmI.calls.mostRecent().args[0]).toEqual("I");
- });
- });
jasmine.createSpyObj
使用jasmine.createSpyObj
可以模拟多个spies。给jasmine.createSpyObj
传入一个字符串数组,返回一个对象,字符串数组的每一项都是它的spy类型的属性。
- describe("Multiple spies, when created manually", function() {
- var tape;
- beforeEach(function() {
- tape = jasmine.createSpyObj('tape', ['play', 'pause', 'stop', 'rewind']);
- tape.play();
- tape.pause();
- tape.rewind(0);
- });
- it("creates spies for each requested function", function() {
- expect(tape.play).toBeDefined();
- expect(tape.pause).toBeDefined();
- expect(tape.stop).toBeDefined();
- expect(tape.rewind).toBeDefined();
- });
- it("tracks that the spies were called", function() {
- expect(tape.play).toHaveBeenCalled();
- expect(tape.pause).toHaveBeenCalled();
- expect(tape.rewind).toHaveBeenCalled();
- expect(tape.stop).not.toHaveBeenCalled();
- });
- it("tracks all the arguments of its calls", function() {
- expect(tape.rewind).toHaveBeenCalledWith(0);
- });
- });
其他跟踪属性
spy的任何调用都可以使用calls
属性跟踪
.calls.any()
如果spy没有被调用过,则返回false,否则返回true
.calls.count()
返回spy被调用的次数
.calls.argsFor(index)
返回spy被第index次调用时的参数
.calls.allArgs()
返回spy所有被调用的参数
.calls.all()
返回spy所有被调用的this
上下文和参数
.calls.mostRecent()
返回spy最近一次被调用的this
上下文和参数
.calls.first()
返回spy第一次被调用的this
上下文和参数
.calls.reset()
清空spy的所有跟踪,看看他们的用法,点这里看在线运行效果:
- describe("Jasmine Spy的跟踪属性", function() {
- var foo, bar = null;
- beforeEach(function() {
- foo = {
- setBar: function(value) {
- bar = value;
- }
- };
- spyOn(foo, 'setBar');
- });
- it(".calls.any()示例", function() {
- expect(foo.setBar.calls.any()).toEqual(false);
- foo.setBar();
- expect(foo.setBar.calls.any()).toEqual(true);
- });
- it(".calls.count()示例", function() {
- expect(foo.setBar.calls.count()).toEqual(0);
- foo.setBar();
- foo.setBar();
- expect(foo.setBar.calls.count()).toEqual(2);
- });
- it(".calls.argsFor(index)示例", function() {
- foo.setBar(123);
- foo.setBar(456, "baz");
- expect(foo.setBar.calls.argsFor(0)).toEqual([123]);
- expect(foo.setBar.calls.argsFor(1)).toEqual([456, "baz"]);
- });
- it(".calls.allArgs()示例", function() {
- foo.setBar(123);
- foo.setBar(456, "baz");
- expect(foo.setBar.calls.allArgs()).toEqual([
- [123],
- [456, "baz"]
- ]);
- });
- it(".calls.all()示例", function() {
- foo.setBar(123);
- expect(foo.setBar.calls.all()).toEqual([{
- object: foo,
- args: [123]
- }]);
- });
- it(".calls.mostRecent()示例", function() {
- foo.setBar(123);
- foo.setBar(456, "baz");
- expect(foo.setBar.calls.mostRecent()).toEqual({
- object: foo,
- args: [456, "baz"]
- });
- });
- it(".calls.first()示例", function() {
- foo.setBar(123);
- foo.setBar(456, "baz");
- expect(foo.setBar.calls.first()).toEqual({
- object: foo,
- args: [123]
- });
- });
- it(".calls.reset()示例", function() {
- foo.setBar(123);
- foo.setBar(456, "baz");
- expect(foo.setBar.calls.any()).toBe(true);
- foo.setBar.calls.reset();
- expect(foo.setBar.calls.any()).toBe(false);
- });
- });
– 下一篇讲一下异步代码测试 –
- Javascript测试框架Jasmine(五):Spies
- Javascript测试框架Jasmine
- Javascript测试框架Jasmine(一):简介
- Javascript测试框架Jasmine(二):Matchers
- Javascript测试框架Jasmine(六):异步代码测试
- Javascript测试框架Jasmine(七):jqPaginator测试实例
- Javascript测试框架Jasmine(四):自定义Matcher
- JavaScript 测试框架 ( QUnit , javascript code coverage , JSCoverage , Pavlov , Jasmine )
- Javascript 单元测试框架-Jasmine
- Jasmine: JavaScript 单元测试框架
- Javascript测试框架Jasmine(三):Setup、Teardown、嵌套describe等
- 进入Jasmine的世界——超强Javascript测试框架
- JS测试框架-Jasmine简介
- jasmine测试框架学习笔记
- 通过Jasmine和Guard自动测试JavaScript
- javascript 的 jasmine 的测试语句
- Javascript单元测试框架比较Qunit VS Jasmine
- Javascript单元测试框架比较Qunit VS Jasmine
- Javascript测试框架Jasmine(四):自定义Matcher
- SHUOJ 2333
- ubuntu安装mysql可视化工具MySQL-workbench及简单操作
- caffe中不同层的含义和卷积的计算方式
- 泊松融合-Possion Blending
- Javascript测试框架Jasmine(五):Spies
- Keras如何构造简单的CNN网络
- BZOJ1597[Usaco2008 Mar]土地购买(洛谷P2900)
- 解决ScrollView嵌套RecyclerView出现item显示不全的问题
- JavaEE初级了解
- 2017.11.9第十一周周中总结
- metasploit 情报搜集技术【5】漏洞测试信息数据库与共享
- 神经网络是包治百病的狗皮膏药吗?
- Linux ssh免密码登录