Alcadur Alcadur - 6 months ago 17
Javascript Question

test new object instance (jasmine)

I have tests run by karma, in one of them I create

new instance
of object and call
function
where is used
this
. On normal browser
this
is reference to current instance but in test after
console.log
it I see:


Object{document: < !-- This is the execution context.

Loaded within the iframe. Reloaded before every execution run.


Why?



// createing the object

window.gr = window.gr || {};

gr.Notification = (function () {
function Notification(node, message) {
this.liveTime = 5000;
this.template = this.createTemplate(message);
this.node = null;
this.appendTo(node);

setTimeout(this.remove, this.liveTime);
}

Notification.prototype = {
createTemplate: function (message) {
var notification = document.createElement("div");
notification.className = "notification";

var _message = document.createTextNode(message);
notification.appendChild(_message);

return notification;
},
appendTo: function(node){
this.node = node.appendChild(this.template);
},
remove: function(){
console.log(this)
this.node.parentNode.removeChild(this.node);
}
};

return Notification;
})();


//test

beforeEach(function(){
Notification = gr.Notification;
jasmine.clock().install();
});

it("should remove notification after 5s", function(){
new Notification(document.body);

jasmine.clock().tick(5001);

expect(document.querySelectorAll(NOTIFICATION_SELECTOR).length).toEqual(0);
});




kzg kzg
Answer

your this references to window, because you call setTimeout, which is method of window object, so this inside that method points to window,

you could do something like that:

function Notification(node, message) {
        this.liveTime = 5000;
        this.template = this.createTemplate(message);
        this.node = null;
        this.appendTo(node);

        var self = this;

        setTimeout(function() {
            self.remove()
        }, self.liveTime);

    }