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

javascript - Setting global variables in jasmine for angularjs - Stack Overflow

programmeradmin3浏览0评论

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.

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.

Share Improve this question asked Jun 16, 2015 at 20:07 imgr8imgr8 5114 gold badges11 silver badges25 bronze badges 6
  • looks like you have declared environment variables in IIFE function that will restrict scope of it. – Pankaj Parkar Commented Jun 16, 2015 at 20:10
  • So are you saying I should convert this to an angular constant or value? – imgr8 Commented Jun 16, 2015 at 20:20
  • yes...otherwise you need to make it global thing without wrapping it into IIFE pattern? – Pankaj Parkar Commented Jun 16, 2015 at 20:22
  • So I removed the IIFE wrapper, and tried setting the values using $window and it still doesn't work. Still getting the same error. – imgr8 Commented Jun 16, 2015 at 20:29
  • I added this: module(function($provide) { var pk = {} pk.env = {}; pk.env.baseUrl = ''; $provide.value('$window', pk); }); – imgr8 Commented Jun 16, 2015 at 20:31
 |  Show 1 more ment

2 Answers 2

Reset to default 6

As pretty much already answered here, you can also declare a global variable within your test file

var globalVar = "something";

describe('Your test suit', function() {
    ...
});

and if you are using Karma you can edit the karma.conf.js file to define it

 // list of files / patterns to load in the browser
 files: [
    ...,
    'file-containing-the-global-variable.js'
 ],

You should avoid using the globals in Angular pletely.

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)

发布评论

评论列表(0)

  1. 暂无评论