2
votes

I am new to web worker . I have written a web worker which gets message and reads data on onmessage event and after that it makes an ajax/http call to get data. Once data is returned from ajax/http call it posts message back using postMessage event. Now I want to know how to unit test this web Worker using Jasmine and Karma . I tried testing it but unable to Mock the http call inside web worker. Below is my code. Thanks In advance.

worker.js

(function () {
'use strict';  var startDate, endDate, token, initialized;

var http = {};

/*  Code To make http request - Starts */
http.x = function () {
    if (typeof XMLHttpRequest !== 'undefined') {
        return new XMLHttpRequest();
    }
    var versions = [
        "MSXML2.XmlHttp.6.0",
        "MSXML2.XmlHttp.5.0",
        "MSXML2.XmlHttp.4.0",
        "MSXML2.XmlHttp.3.0",
        "MSXML2.XmlHttp.2.0",
        "Microsoft.XmlHttp"
    ];

    var xhr;
    for (var i = 0; i < versions.length; i++) {
        try {
            xhr = new ActiveXObject(versions[i]);
            break;
        } catch (e) {
        }
    }
    return xhr;
};

http.send = function (url, callback, method, data, async, headerToken) {
    if (async === undefined) {
        async = true;
    }
    var x = http.x();
    x.open(method, url, async);
    if (headerToken !== null && headerToken !== "") {
        x.setRequestHeader("Authorization", "Bearer " + headerToken);
    }
    x.onreadystatechange = function () {
        if (x.readyState === 4 && x.responseText !== "" && x.responseText !== undefined && x.responseText !== null) {
            callback(JSON.parse(x.responseText));
        }
    };
    x.send(data);
};

http.get = function (url, data, callback, async, headerToken) {
    var query = [];
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
        }
    }
    http.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async, headerToken);
};
/*  Code To make http request  - ends */


var postOpenOrdersTile = function (result) {
    if (result) {
        postMessage('<div id="openOrdersTile" class="tileContent">' +result.TotalOpenOrders +'</div>');
    }

};

function run(url) {
    var baseUrl = url;
    var openOrdersTilesUrl = baseUrl + "/DashboardTiles/GetOpenOrderTileValues";
    http.get(openOrdersTilesUrl, createDashboardTileInput(startDate, endDate), postOpenOrdersTile, true, token);
}

var load = function (response) {
    var baseUrl = response.base + response.api;
    run(baseUrl);
}

/* Code To triggere Worker - onmessage */
self.onmessage = function (msg) {
    if (msg.data.baseUrl && !initialized) {
        self.importScripts(msg.data.baseUrl + '/BaseApp/Scripts/moment.js');
        startDate = msg.data.fromDate;
        endDate = msg.data.toDate;
        token = msg.data.token;
        http.get(msg.data.baseUrl + '/CardioDashboard/config.json', '', load, true, '');
    }
};}());

WorkerSpec.js

define([], 

function () {  'use strict'  

 describe('Web Worker : Tiles Sharing web Worker', function () {        .
 var worker, data   ;         

 http = { get: function () { return {} } };
    beforeEach(function () {
        worker = new Worker('path/Worker.js');
        data = {
            baseUrl: "xyz",
            fromDate: '2017-04-13',
            toDate: '2017-04-07',
            token: ''             
        };
        worker.postMessage(data);
    });

    afterEach(function () {

    });


    it('Tests the Webworker', function (done) {
        spyOn(http, 'get').and.returnValue({});
        spyOn(window, 'postOpenOrdersTile').and.callFake(function () {
            return {};
        });
        worker.addEventListener('message', function (e) {
            if (e.data) {
                expect(e.data).toBe('<div id="openOrdersTile" class="tileContent">45</div>');                        
            }
            if (triggerCount === 6) {
                done();
            }
        });

    });
});});
1
What's the output of your test?myfashionhub
Output was Expected <div id="openOrdersTile" class="tileContent">null</div> to be equal to<div id="openOrdersTile" class="tileContent">45</div>. Since web worker is actually making the http call but our service needs token to be passed in header.Since it is unit test am not passing the actual token. Since am just testing the web workers behaviour I dont want to make htpp call instead I need to mock the http and return some value I need. Thanks for the replypavan

1 Answers

0
votes

The reason the output is <div id="openOrdersTile" class="tileContent">null</div> is because the argument for postOpenOrdersTile is null. I'm not sure if you're really testing anything useful because you have to mock everything. But try mocking the return value of http.get: {TotalOpenOrders: 45}.

You can make the Worker an constructor and attach http to it:

var Worker = function() {
  this.http = {
    send: function() {
       // do something
    },
    get: function() {
      // do something
    }
  };
}

In test: spyOn(worker.http, 'get').and.returnValue({});