2014-09-05 75 views
6

我想窥视一个构造函数,并告诉它使用jasmine调用了多少次。我通常会做这样的事情的目标对象的方法:使用jasmine构造函数间谍

spyOn(lib,'methodName') 

但在情况下,我想窥探actualy构造函数,因此我已经试过:

spyOn(lib); 


it('lib should be instantiated for each matching element', function() { 
    spyOn(lib); 
    expect(lib.calls.count()).toEqual(2); 
}); 

不幸的是,这只是给了我一个在控制台中的错误:

"Error: undefined() method does not exist in ..." 

我怎么能窥探构造函数?

+2

尝试使用'spyOn(window,'lib')' – javiyu 2014-09-05 15:06:14

+0

使用'lib.callCount' – inf3rno 2014-09-05 17:18:52

+0

可能重复[Jasmine - Spying on在构造函数中调用方法](http://stackoverflow.com/questions/8733978/jasmine-spying-on-a-method-call-within-a-constructor) – 2015-07-30 20:36:48

回答

11

spyOn()函数只能替换对象属性,所以你唯一能做的就是窥探原型。现在,如果你要窥探真正的类的原型,它会干扰其他测试,所以你必须使用原型继承。

你可以做这样的事情:

var mockClass = function (Subject) { 
    var Surrogate = function() { 
     Surrogate.prototype.constructor.apply(this, arguments); 
    }; 
    Surrogate.prototype = Object.create(Subject.prototype); 
    Surrogate.prototype.constructor = Subject; 
    return Surrogate; 
}; 

一些测试:

var My = function (a) { 
    this.init(a); 
}; 
My.prototype = { 
    init: function (a) { 
     this.setA(a); 
    }, 
    setA: function (a) { 
     this.a = a; 
    } 
}; 

var Mock = mockClass(My); 
spyOn(Mock.prototype, "constructor").andCallThrough(); 
spyOn(Mock.prototype, "init"); 

var m = new Mock(1); 

expect(Mock.prototype.init).toBe(m.init); 
expect(My.prototype.init).not.toBe(m.init); 
expect(m.constructor).toHaveBeenCalledWith(1); 
expect(m.init).toHaveBeenCalledWith(1); 
expect(m.a).toBeUndefined(); 
m.setA(1); 
expect(m.a).toBe(1); 

spyOn(Mock.prototype, "setA").andCallFake(function (a) { 
    this.a = a + 1; 
}); 
m.setA(1); 
expect(m.setA).toHaveBeenCalledWith(1); 
expect(m.a).toBe(2); 

如果你的代码使用x.constructor基于类型检查不能在constructor间谍。但我认为这只能通过集成测试和设计糟糕的代码来实现......

相关问题