最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Spy on a constructor using jasmine - Stack Overflow

programmeradmin4浏览0评论

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:

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?

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:

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?

Share Improve this question asked Sep 5, 2014 at 15:05 Mike RifginMike Rifgin 10.7k22 gold badges77 silver badges115 bronze badges 2
  • 2 Try with spyOn(window, 'lib') – javiyu Commented Sep 5, 2014 at 15:06
  • possible duplicate of Jasmine - Spying on a method call within a constructor – Heretic Monkey Commented Jul 30, 2015 at 20:36
Add a comment  | 

1 Answer 1

Reset to default 17

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.

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...

发布评论

评论列表(0)

  1. 暂无评论