Поставщик шпионских программ на этапе настройки в angular.js приложение

#javascript #angularjs #unit-testing #karma-jasmine

#javascript #angularjs #модульное тестирование #карма-жасмин

Вопрос:

Я пишу модульные тесты для Angular.js приложение (с karma и jasmine), и я хочу протестировать определенное поведение на этапе настройки модуля. Я хотел бы подтвердить, что вызывается определенная функция поставщика. Я думал, что смогу сделать это с помощью шпионского метода поставщика, но получить доступ к поставщику до «ожидать» оказалось довольно сложно. Вот несколько примеров кода:

Код модуля (тестируется)

 var myApp = angular.module('myApp', ['restangular']);
myApp.config(['RestangularProvider', function (RestangularProvider) {
    RestangularProvider.setBaseUrl('http://someurl:someport/');
}]);
  

Я пробовал различные решения, чтобы получить ссылку на RestangularProvider и применить к нему spy, и все это не удалось. Самым близким, что я смог получить, был приведенный ниже код:

Модульный тестовый код

 describe("Test if setBaseUrl was called", function () {
    var RestangularProvider;
    beforeEach(module('myApp', function(_RestangularProvider_) {
        RestangularProvider = _RestangularProvider_;
        spyOn(RestangularProvider, "setBaseUrl").and.callThrough();
    }));

    it("should call setBaseUrl.", function() {
        expect(RestangularProvider.setBaseUrl).toHaveBeenCalled();
    });
});
  

Я действительно получаю ссылку на RestangularProvider, но функция «config» модуля вызывается до этого, поэтому я думаю, что шпион не настраивается.

Я нашел сообщение, в котором автор решил аналогичную ситуацию с помощью «обхода», протестировав настроенный «сервис» вместо тестирования фактического вызова метода поставщика. В приведенном выше примере я бы протестировал Restangular.configuration.baseUrl в моем expect вместо тестирования фактического вызова setBaseUrl метода поставщика, но, похоже, в определенных ситуациях этого было бы недостаточно.

Я довольно новичок в Angular.js так что это может быть просто случай полного невежества относительно всей «фазы конфигурации тестирования», поэтому, если это так, пожалуйста, не стесняйтесь указывать мне прямо :]

Есть предложения, критические замечания или указания?

Ответ №1:

Я, наконец, решил проблему, выделив модуль, за поставщиком которого я хотел следить, в отдельный блок «Перед каждым». Измененный код приведен ниже, но я все же был бы признателен за любые комментарии относительно общей идеи о том, действительно ли это «адекватный тест».

 describe("Test if setBaseUrl was called", function () {
    var RestangularProvider;
    //Setup the spy.
    beforeEach(function () {

      module("restangular", function(_RestangularProvider_) {
        RestangularProvider = _RestangularProvider_;
        spyOn(_RestangularProvider_, 'setBaseUrl').and.callThrough();
      });
    });

    beforeEach(module('myApp'));

    it("should call setBaseUrl.", function() {
        expect(RestangularProvider.setBaseUrl).toHaveBeenCalled();
    });
});
  

Ответ №2:

Как описано в OP выше, вам необходимо получить поставщика перед вызовом модуля, который вы хотите протестировать.
Однако нет необходимости разделять его на два beforeEach блока. Вы также должны вызвать inject() функцию (даже если вам нечего вводить) в конце beforeEach блока.

 describe('Test if setBaseUrl was called', function () {
  var RestangularProvider;
  //Setup the spy.
  beforeEach(function () {

    module('restangular', function(_RestangularProvider_) {
      RestangularProvider = _RestangularProvider_;
      spyOn(_RestangularProvider_, 'setBaseUrl').and.callThrough();
    });

    module('myApp');

    inject();
  });

  it('should call setBaseUrl.', function() {
    expect(RestangularProvider.setBaseUrl).toHaveBeenCalled();
  });
});
  

Источник:http://java.dzone.com/articles/unit-testing-config-and-run