Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Change Constant Value that gets passed to Config for Unit Test

Is there anyway to change the constant value that gets sent to the config function of the module for a Unit Test?

I have the following (fiddle here):

//--- CODE --------------------------
var module = angular.module("myApp", []);
module.constant("myConstant", "foo");
module.provider("awesomeStuff", function () {
    var value;

    this.setValue = function (val) {
        value = val;
    };

    this.$get = function () {
        return {
            myValue: value
        };
    };
});
module.config(function (myConstant, awesomeStuffProvider) {
    //want to mock myConstant
    awesomeStuffProvider.setValue(myConstant);
});



//--- SPECS -------------------------
describe("foo", function() {
    beforeEach(angular.mock.module("myApp", function ($provide) {
        //Attempt to override the myConstant value that gets passed to config
        $provide.constant("myConstant", "bar");
    }));

  it("has a value of bar", inject(function(awesomeStuff, $injector) {
    expect($injector.get("myConstant")).toBe("bar");
    expect(awesomeStuff.myValue).toBe("bar");
  }));
});

I know this is a trivial example, but I want to know if its possible to get a different constant to be injected into the config... I know it is possible to get a reference to the provider and call setValue function from unit test (i.e. configuring provider via this SO post), but this is not what I'm looking for.

Thanks for any help.

like image 939
Patrick Avatar asked Aug 13 '14 20:08

Patrick


1 Answers

Consider the following:

beforeEach(angular.mock.module("myApp"));

This will load the module and execute the registered config functions.

In your case you have:

beforeEach(angular.mock.module("myApp", function ($provide) {
    //Attempt to override the myConstant value that gets passed to config
    $provide.constant("myConstant", "bar");
}));

What happens now is basically the same as if you had the following:

var module = angular.module("myApp", []);

... Constant and Provider omitted ...

module.config(function(myConstant, awesomeStuffProvider) {

  awesomeStuffProvider.setValue(myConstant);
});

module.config(function($provide) {

  $provide.constant("myConstant", "bar");
});

As the registered config functions will be executed in order of registration this will not have the desired result.

If you need to mock a constant before it's used in any config function I would recommend to put it in a separate module.

Depending on your use case, you can now either:

  1. Create two versions of this module - one for production and one for the tests
  2. Create only the real version and mock the constant in the test

The second case would look something like this:

App:

angular.module("configuration", []).constant("myConstant", "foo");

var module = angular.module("myApp", ["configuration"]);

module.provider("awesomeStuff", function () {
    var value;

    this.setValue = function (val) {
        value = val;
    };

    this.$get = function () {
        return {
            myValue: value
        };
    };
});

module.config(function (myConstant, awesomeStuffProvider) {
    awesomeStuffProvider.setValue(myConstant);
});

Test:

describe("foo", function () {

    beforeEach(function () {

        angular.mock.module("configuration", function ($provide) {
            $provide.constant("myConstant", "bar");
        });

        angular.mock.module("myApp", function () {
            // Something else
        });
    });

    it("has a value of bar", inject(function (awesomeStuff, $injector) {
        expect($injector.get("myConstant")).toBe("bar");
        expect(awesomeStuff.myValue).toBe("bar");
    }));
});

JSFiddle: http://jsfiddle.net/f0nmbv3c/

like image 138
tasseKATT Avatar answered Sep 30 '22 03:09

tasseKATT