javascript 使用 jasmine 监视构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25688880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spy on a constructor using jasmine
提问by Mike Rifgin
I want to spy on a constructor function and tell how many times it's been called using jasmine. I'd usually do something like this to target a method of an object:
我想监视一个构造函数并告诉它使用 jasmine 被调用了多少次。我通常会做这样的事情来定位一个对象的方法:
spyOn(lib,'methodName')
but in the case I'm trying to spy on the actualy constructor so I've tried:
但在这种情况下,我试图监视实际的构造函数,所以我尝试过:
spyOn(lib);
it('lib should be instantiated for each matching element', function () {
spyOn(lib);
expect(lib.calls.count()).toEqual(2);
});
Unfortunately this just gives me an error in the console:
不幸的是,这只会在控制台中给我一个错误:
"Error: undefined() method does not exist in ..."
how can I spy on the constructor?
我如何监视构造函数?
回答by inf3rno
The spyOn()
function can only replace object properties, so the only thing you can do is spying on the prototype. Now if you would spy on the prototype of the real class, it would interfere with the other tests, so you have to use prototypal inheritance.
该spyOn()
函数只能替换对象属性,因此您唯一能做的就是监视原型。现在如果你要窥探真实类的原型,它会干扰其他测试,所以你必须使用原型继承。
You can do something like this :
你可以这样做:
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;
};
Some tests:
一些测试:
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);
You cannot spy on the constructor
if your code uses an x.constructor
based type checking. But I think this can happen only by integration tests, and by badly designed codes...
constructor
如果您的代码使用x.constructor
基于类型检查,您就无法窥探。但我认为这只能通过集成测试和设计糟糕的代码发生......