AngularJS更改常量值,传递给Config进行单元测试

时间:2014-08-13 20:23:22

标签: angularjs unit-testing jasmine

无论如何都要更改发送到单元测试的模块配置功能的常量值吗?

我有以下(小提琴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");
  }));
});

我知道这是一个简单的例子,但是我想知道是否有可能将不同的常量注入到配置中...我知道可以获得对提供者的引用并从中调用setValue函数单元测试(即通过this SO post配置提供商),但这不是我正在寻找的。

感谢您的帮助。

1 个答案:

答案 0 :(得分:21)

请考虑以下事项:

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

这将加载模块并执行已注册的配置功能。<​​/ p>

在你的情况下,你有:

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

现在发生的情况基本上与您拥有以下内容相同:

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");
});

由于注册的配置功能将按注册顺序执行,因此无法获得所需的结果。

如果你需要在任何配置函数中使用之前模拟一个常量,我建议把它放在一个单独的模块中。

根据您的使用情况,您现在可以:

  1. 创建此模块的两个版本 - 一个用于生产,一个用于测试
  2. 仅创建真实版本并在测试中模拟常量
  3. 第二种情况看起来像这样:

    应用:

    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);
    });
    

    测试:

    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/