AngularJS 1.5和打字稿中的单元测试组件



致力于将一些旧的损坏的AngularJS单元测试转换为打字稿,并遇到此错误:

Error: [$injector:unpr] Unknown provider: myComponentDirectiveProvider <- myComponentDirective

在我看到的AngularJS单元测试的每个示例中,它们都有一个主模块,其中所有内容都将其注入使用angular.mock.module('theWholeStinkingApp')的主模块。这对一些教程很好,但是我正在处理一个非常大的应用程序,其中包括数百个组件和数十个服务。更不用说过滤器和其他指令了。仅将整个应用程序注入单元测试不起作用。我也不认为启动整个应用程序以单元测试组件是一个好主意(当您必须在每个测试中包含自己拥有的所有内容时,都会打败单元测试的目的(。

对于测试服务,我可以在beforeEach中的测试中创建我的模块,因此我要嘲笑依赖项,但是注入我要测试的真实服务:

angular.mock.module(($provide) => {
  $provide.service('firstDependency', FirstDependencyMock);
  $provide.service('secondDependency', SecondDependencyMock);
  $provide.service('serviceIWantToTest', ServiceIWantToTest);
});

我无法弄清楚如何执行此操作并注入组件。任何帮助,将不胜感激。

请记住,我不想要angular.mock.module('theWholeApp')才能使此工作。我只想创建一个模拟模块并将我的组件附加到它。

这是我正在做的事情的纤细版本。

组件看起来像这样

angular.module('theWholeApp', [])
  .component('myComponent', {
    controller: MyComponentController, // class is defined elsewhere
    templateUrl: 'path/to/my/template.html'
  )
  ... // 100+ other components;

这是测试:

describe('MyComponent', () => {
  beforeEach(() => {
    // angular.mock.module('theWholeApp'); This is not an option.
    // Creating a mock module with just the dependencies I need for this test
    angular.mock.module(($provide) => {
        $provide.service('firstDependency', FirstDependencyMock);
        $provide.service('secondDependency', SecondDependencyMock);
    });
    // Tried adding this to register the controller, but it doesn't help.  
    angular.mock.module(($controllerProvider) => {
        $controllerProvider.register('MyComponentController', MyComponentController);
    });
    angular.mock.inject(($injector) => {
      $rootScope = $injector.get('$rootScope');
      $componentController = $injector.get('$componentController');
      firstDependency= $injector.get('firstDependency');
      secondDependency= $injector.get('secondDependency');
      $scope = $rootScope.$new();
    });
  });
  describe('doSomething', () => {
    it('exists', () => {
      controller = $componentController('myComponent', {$scope});
        expect(controller.doSomething).toBeDefined();
      });
  });
});

显然,这不是实时代码,而只是表示。希望我能正确地得到所有编造的名字。关键是,我想创建一个模拟模块并将我的组件添加到它,以便调用$componentController('myComponent', {$scope})的工作。

谢谢!

好吧,我想出的答案很简单,但是我从未在任何地方看到它。如果有人能告诉我为什么这是一个坏主意,并提出更好的建议,我全都为此。

答案是只创建要的模块,然后立即将其添加到测试中。

describe('MyComponent', () => {
  // Create a new module with the things you need.
  // Putting it outside the "beforeEach" because it only needs to be created once.
  angular.module('myComponentTestModule', [])
    .component('myComponent', {
      controller: MyComponentController, // class is defined elsewhere
      templateUrl: 'path/to/my/template.html'
    )
    .service('firstDependency', FirstDependencyMock)
    .service('secondDependency', SecondDependencyMock);
  beforeEach(() => {
    // Add the new module to the test suite
    angular.mock.module('myComponentTestModule');
    angular.mock.inject(($injector) => {
      $rootScope = $injector.get('$rootScope');
      $componentController = $injector.get('$componentController');
      firstDependency= $injector.get('firstDependency');
      secondDependency= $injector.get('secondDependency');
      $scope = $rootScope.$new();
    });
  });
  describe('doSomething', () => {
    it('exists', () => {
      controller = $componentController('myComponent', {$scope});
        expect(controller.doSomething).toBeDefined();
      });
  });
});

最新更新