Модульный тест AngularJS для сервиса: $ urlMatcherFactory выдает неизвестную ошибку - PullRequest
0 голосов
/ 31 мая 2018

У меня есть несколько вопросов, чтобы написать правильный модульный тест для службы, используя jasmine в качестве платформы и karma в качестве тестового прогона.

вот что я реализовал в example-service.js :

export default class ExampleService {
constructor($resource, $http, $urlMatcherFactory) {
'ngInject';

this.$resource = $resource;
this.$http = $http;
this.$urlMatcherFactory = $urlMatcherFactory;
}

exampleMethodOne() {
//some code lines
}

exampleMethodTwo() {
//some code lines 
}

}
ExampleService.selector = 'myExampleService';

Вот что я написал в своем тесте example-service.test.js

        let myExampleService, $httpBackend, $urlMatcherFactory;

          beforeEach(() => {
            angular
              .module('exampleApp', ['ngResource'])
              .service(ExampleService.selector, ExampleService);
            angular.mock.module('exampleApp');
          });

          beforeEach(inject((_myExampleService_, _$httpBackend_, 
_$urlMatcherFactory_) => {
            myExampleService = _myExampleService_;
            $httpBackend = _$httpBackend_;
            $urlMatcherFactory = _$urlMatcherFactory_;
          })); 

Я импортировал angular-mocks.js, angular-resource.js и example-service.js

, когда я попробую этот сценарий, консоль выдаст ошибку Error: [$injector:unpr] Unknown provider: $urlMatcherFactoryProvider <- $urlMatcherFactory <- myExampleService.

, пожалуйста, помогите мне решить эту проблему.

1 Ответ

0 голосов
/ 31 мая 2018

Полагаю, $urlMatcherFactory относится к службе маршрутизатора пользовательского интерфейса , а маршрутизатор пользовательского интерфейса не загружен.

Не рекомендуется использовать настоящий маршрутизатор в модульных тестах, поскольку он предоставляет дополнительные движущиеся части.и ломает изоляцию между единицами.Как правило, каждый модуль, кроме тестируемого, должен быть проверен.

$urlMatcherFactory Методы-заглушки должны быть настроены так, чтобы они возвращали ожидаемые значения.Так как они используются во время ExampleService построения, они должны быть настроены до создания экземпляра службы:

  let removeAllUrlMock;

  beforeEach(() => {
    removeAllUrlMock = jasmine.createSpyObj('removeAllUrl', ['format']);
    $urlMatcherFactory = jasmine.createSpyObj('urlMatcherFactory', ['compile']);
    $urlMatcherFactory.compile.and.returnValue(removeAllUrlMock);

    angular
      .module('exampleApp', ['ngResource'])
      .service(ExampleService.selector, ExampleService);
    angular.mock.module('exampleApp');
    angular.mock.module({ $urlMatcherFactory });
  });

Это можно проверить с помощью:

expect($urlMatcherFactory.compile).toHaveBeenCalledOnce();
expect($urlMatcherFactory.compile).toHaveBeenCalledWith('../api/v1/user/{Id}/remove/all');
expect(myExampleService.removeAllUrl).toBe(removeAllUrlMock);

Тогда конкретные вызовы removeAllUrl могутпроверяться и проверяться при использовании:

removeAllUrlMock.format.and.returnValue('../api/v1/user/foo/remove/all');
myExampleService.removeProduct('foo');
expect(removeAllUrlMock.format).toHaveBeenCalledOnce();
expect($urlMatcherFactory.compile).toHaveBeenCalledWith(
  jasmine.objectContaining({ id: 'foo' })
);

Поскольку $urlMatcherFactory - это сервисная служба, которая не предоставляет много движущихся частей и должна быть предсказуемой, ее можно альтернативно импортировать и использовать напрямую, без модуля маршрутизатора пользовательского интерфейса.:

import { UrlMatcherFactory } from '@uirouter/angularjs';

...

  beforeEach(() => {
    angular
      .module('exampleApp', ['ngResource'])
      .service(ExampleService.selector, ExampleService);
    angular.mock.module('exampleApp');
    angular.mock.module(($provide) => {
      $provide.service('$urlMatcherFactory', UrlMatcherFactory });
    });
  });

Тогда это просто надо шпионить:

spyOn(myExampleService, 'removeAllUrl').and.callThrough();
myExampleService.removeProduct('foo');
expect(removeAllUrlMock.format).toHaveBeenCalledOnce();
expect($urlMatcherFactory.compile).toHaveBeenCalledWith(
  jasmine.objectContaining({ id: 'foo' })
);
...