imgr8 imgr8 - 2 months ago 26
Javascript Question

Setting global variables in jasmine for angularjs

I have an angular application with some global environment variables defined in an env.js file:

(function(sp) {
'use strict';

pk.env = pk.env || {};

// localhost
pk.env.baseUrl = 'http://localhost:8080/';
})(typeof exports === 'undefined' ? (this.pk = this.pk || {}) : exports);


These variables are used in multiple factories to make REST API calls:

'use strict';

angular.module('pkApp').factory('pkFactory', PKFactory);

function PKFactory($http) {
var urlBase = pk.env.baseUrl;
var apiUrl = 'v1/data';
var _pkFactory = {};

_pkFactory.getData = function() {
return $http.get(urlBase + apiUrl);
};


return _pkFactory;
}


I am writing unit tests for this factory using Jasmine and I keep getting the error:


ReferenceError: Can't find variable: pk


If I remove this variable reference from the factory, the tests run fine.

'use strict';

console.log('=== In pk.factory.spec');

describe('Unit: pkFactory', function() {

beforeEach(module("pkApp"));

var $httpBackend, $rootScope, pkFactory;

beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');

$httpBackend.when('GET', 'v1/data').respond('Not found');

pkFactory = $injector.get('pkFactory');

}));

afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});

it('expects getData method to be defined', function(){
expect(pkFactory.getData()).toBeDefined();
$httpBackend.flush();
});
})


How do I inject value of 'pk.env.baseUrl' into the factory? I have tried using $window, but it didn't work.

Answer

You should avoid using the globals in Angular completely.

Convert the file to an angular value or constant:

angular.module('pkApp').value('pk', pk);

now you can change pkFactory to get the pk object injected

function PKFactory($http, pk) {
    // pk is no longer from global scope, but injected from angular as an argument
    var urlBase = pk.env.baseUrl;
    var apiUrl = 'v1/data';
    var _pkFactory = {};

    _pkFactory.getData = function() {
        return $http.get(urlBase + apiUrl);
    };


    return _pkFactory;
}

and in tests, you can now mock the pk to a different value (or not do anything and use the one from code)

Comments