jeudi 24 mars 2016

'this' scoping in jasmine unit test

I was testing an angular service which is exposing a method that relies on the context it is called with. The following is my service method -

modelGetterSetter(value, model) {

    if (value !== undefined && model !== undefined) {
        model = model.split('.').reverse();
        var current = this;
        while (model.length - 1) {
            if (typeof current !== 'object') return undefined;
            current = current[model.pop()];
        }
        current[model.pop()] = value;
    }
    else if(model !== undefined) {
        value = this.Utils.valueOf(this, model);
    }
    else {
        throw new Error('Model is undefined')
    }

    return value;
}

I was trying to test the else if block of this method and this was my initial attempt -

describe('modelGetterSetter Method without a value', function () {
    this.obj = {
        foo: {
            bar: 'val'
        }
    };
    let val,
        that = this;
    that.Utils = utils;
    beforeEach(()=> {
        "use strict";
        val = utils.modelGetterSetter.call(that, undefined, 'obj.foo.bar');
    });
    it('should return correct value when supplied with valid model and undefine value', ()=> {
        expect(val).toBe('val');
    });

});

However this was resulting in the following error -

TypeError: 'undefined' is not an object (evaluating 'this.Utils.valueOf')

I managed to fix this by declaring assigning the Utils service inside the beforeEach like so -

describe('modelGetterSetter Method without a value', function () {
    this.obj = {
        foo: {
            bar: 'val'
        }
    };
    let val,
        that = this;

    beforeEach(()=> {
        "use strict";
        that.Utils = utils;
        val = utils.modelGetterSetter.call(that, undefined, 'obj.foo.bar');
    });
    it('should return correct value when supplied with valid model and undefine value', ()=> {
        expect(val).toBe('val');
    });

});

A little more context - Utils is the service i was trying to test and the modelGetterSetter is a method exposed by this service. Just wondering why doing the assignment in the beforeEach worked but not doing it before it. Even though i call the service method after i do the assignment in both cases.

Aucun commentaire:

Enregistrer un commentaire