Как проверить работоспособность углового декоратора

У меня есть декоратор в Angular, который собирается расширить функциональность службы $ log, и я хотел бы протестировать его, но я не вижу способа сделать это. Вот заглушка моего декоратора:

 angular.module('myApp')
  .config(function ($provide) {

    $provide.decorator('$log', ['$delegate', function($delegate) {
      var _debug = $delegate.debug;
      $delegate.debug = function() {
        var args = [].slice.call(arguments);

        // Do some custom stuff

        window.console.info('inside delegated method!');
        _debug.apply(null, args);
      };
      return $delegate
    }]);

  });

Обратите внимание, что это в основном переопределяет метод $log.debug(), а затем вызывает его после выполнения некоторых пользовательских действий. В моем приложении это работает, и я вижу сообщение 'inside delegated method!' в консоли. Но в моем тесте я не получаю этот вывод.

Как я могу проверить функциональность моего декоратора ??
В частности, как я могу добавить свой декоратор так, чтобы он действительно украшал мою макетную реализацию $log (см. Ниже)?

Вот мой текущий тест (мокко /чай, но это не совсем актуально):

 describe('Log Decorator', function () {
  var MockNativeLog;
  beforeEach(function() {
    MockNativeLog = {
      debug: chai.spy(function() { window.console.log("\nmock debug call\n"); })
    };
  });

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

  beforeEach(function() {
    angular.mock.module(function ($provide) {
      $provide.value('$log', MockNativeLog);
    });
  });

  describe('The logger', function() {
    it('should go through the delegate', inject(function($log) {
      // this calls my mock (above), but NOT the $log decorator
      // how do I get the decorator to delegate the $log module??
      $log.debug();
      MockNativeLog.debug.should.have.been.called(1);
    }));
  });
});
7 голосов | спросил jakerella 18 MarpmTue, 18 Mar 2014 22:33:19 +04002014-03-18T22:33:19+04:0010 2014, 22:33:19

1 ответ


0

Из прикрепленного модуля ( http://j.mp/1p8AcLT ) начальная версия ( в основном) нетронутый код, предоставляемый @jakerella (незначительные корректировки синтаксиса). Я пытался использовать те же зависимости, которые я мог извлечь из оригинального поста. Примечание tests.js:12-14:

 angular.mock.module(function ($provide) {
    $provide.value('$log', MockNativeLog);
});

Это полностью переопределяет собственную службу $log, как и следовало ожидать, с MockNativeLog, представленная в начале тестов потому что angular.mock.module(fn) действует как функция конфигурации для фиктивного модуля . Поскольку функции конфигурации выполняются в порядке FIFO, эта функция забивает украшенную службу $log.

Одним из решений является повторное применение декоратора внутри этой функции конфигурации, как вы можете видеть из версии 2 plunk (постоянная ссылка была бы хороша, Plunker), tests.js:12-18:

 angular.mock.module('myApp', function ($injector, $provide) {
    // This replaces the native $log service with MockNativeLog...
    $provide.value('$log', MockNativeLog);
    // This decorates MockNativeLog, which _replaces_ MockNativeLog.debug...
    $provide.decorator('$log', logDecorator);
});

Однако этого недостаточно. Декоратор @jakerella определяет заменяет метод debug метода $log, вызывая сбой при последующем вызове MockNativeLog.debug.should.be.called(1). Метод MockNativeLog.debug больше не является шпионом, предоставленным chai.spy, чтобы сопоставители не работали.

Вместо этого обратите внимание, что я создал дополнительного шпиона в tests.js:2-8:

 var MockNativeLog, MockDebug;

beforeEach(function () {
    MockNativeLog = {
        debug: MockDebug = chai.spy(function () {
            window.console.log("\nmock debug call\n");
        })
    };
});

Этот код может быть проще для чтения:

 MockDebug = chai.spy(function () {
    window.console.log("\nmock debug call\n");
});

MockNativeLog = {
    debug: MockDebug
};

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

Обратите внимание, что я дополнительно реорганизовал функцию декоратора в глобальную область видимости, чтобы я мог использовать ее в tests.js без необходимости переопределять ее. Лучше было бы сделать рефакторинг в соответствующий Сервис с $provider.value(), но это задание было оставлено в качестве упражнения для студента ... Или кого-то менее ленивый, чем я. : D

ответил AL the X 19 MaramWed, 19 Mar 2014 00:48:05 +04002014-03-19T00:48:05+04:0012 2014, 00:48:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132