【问题标题】:Unit Testing Component in AngularJS 1.5 and TypescriptAngularJS 1.5 和 Typescript 中的单元测试组件
【发布时间】:2018-07-31 02:23:31
【问题描述】:

正在将一些旧的损坏的 AngularJS 单元测试转换为 TypeScript 并遇到此错误:

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}) 就可以了。

谢谢!

【问题讨论】:

    标签: angularjs unit-testing typescript jasmine karma-runner


    【解决方案1】:

    好的,我想出的答案看似简单,但我从未见过任何地方这样做过。如果有人能告诉我为什么这是一个坏主意并提出更好的建议,我完全赞成。

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

    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();
          });
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 1970-01-01
      • 2017-08-17
      • 2017-05-05
      • 2016-10-07
      • 2016-02-17
      • 2018-08-09
      • 2017-09-15
      • 2017-03-04
      相关资源
      最近更新 更多