AngularJS Измените постоянное значение, которое будет передано в Config для модульного теста

Есть ли способ изменить постоянное значение, которое отправляется в конфигурационную функцию модуля для модульного теста?

У меня есть следующее (скрипка здесь):

//--- 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 из модульного теста ( т.е. настройку провайдера через этот SO-сообщение), но это не то, что я ищу.

Спасибо за любую помощь.

Ответ 1

Рассмотрим следующее:

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

Это загрузит модуль и выполнит зарегистрированные функции конфигурации.

В вашем случае у вас есть:

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. Создайте только реальную версию и издевайтесь над константой в тесте

Второй случай будет выглядеть примерно так:

Приложение:

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/