使用Jasmine测试基于组件的应用程序组件,控制器或模板时,引用未定义或为空

时间:2019-07-12 15:25:39

标签: angularjs jasmine components karma-jasmine bdd

我正在为当前正在开发的应用开发测试。 应用使用AngularJS 1.5.8,测试使用Karma和Jasmine。

我正在尝试测试面包屑模块​​,该模块包含以下元素:

breadcrumbs.controller.js

class BreadcrumbsController {
  constructor($rootScope, $state, Menu) {
    'ngInject';

    this.$state = $state;
    this.Menu = Menu;
    this.menuObject = '';
    this.show = false;

    this.updatePath();

    $rootScope.$on('$stateChangeSuccess', () => { this.updatePath(); });
  }

  updatePath() {
    this.showBreadcrumbs();

    if(this.Menu.getMenu()) {
      this.menuObject = this.Menu.getBreadcrumbs(this.$state.current.name);
    }
  }

  getSref(index) {
    let res = ['app'];
    res = res.concat(this.menuObject.slice(0, index + 1));
    return res.join('.');
  }

  showBreadcrumbs() {
    if(this.$state.current.name != 'login' && this.$state.current.name != 'logout') {
      this.show = true;
    } else {
      this.show = false;
    }
  }
}

export default BreadcrumbsController;

breadcrumbs.component.js

import templateUrl from './breadcrumbs.html';
import controller from './breadcrumbs.controller';
import './breadcrumbs.less';

let breadcrumbsComponent = {
  restrict: 'E',
  bindings: {},
  templateUrl,
  controller,
  controllerAs: 'vm'
};

export default breadcrumbsComponent;

breadcrumbs.html:

<div ng-if="vm.show">
  <ol class="breadcrumb">
    <li ng-repeat="menuItem in vm.menuObject track by $index">
      <a href ui-sref="{{vm.getSref($index)}}" ng-if="!$last">{{menuItem | translate}}</a>
      <span ng-if="$last">{{menuItem | translate}}</span>
    </li>
  </ol>
</div>

breadcrumbs.js作为整个模块加载器:

import angular from 'angular';
import breadcrumbsComponent from './breadcrumbs.component';

let breadcrumbsModule = angular.module('breadcrumbs', [])

.component('breadcrumbs', breadcrumbsComponent);

export default breadcrumbsModule;

使用breadcrumbs.spec.js测试:

import BreadcrumbsModule from './breadcrumbs'
import BreadcrumbsController from './breadcrumbs.controller';
import BreadcrumbsComponent from './breadcrumbs.component';
import BreadcrumbsTemplate from './breadcrumbs.html';

describe('Breadcrumbs', () => {
  let $rootScope, makeController;

  beforeEach(window.module(BreadcrumbsModule.name));
  beforeEach(inject((_$rootScope_) => {
    $rootScope = _$rootScope_.$new();
    makeController = () => {
      return new BreadcrumbsController();
    };
  }));

  describe('Module', () => {
    // top-level specs: i.e., routes, injection, naming
  });

  describe('Controller', () => {
    // controller specs
    it('has a show property', () => {
      let controller = makeController();
      expect(controller).to.have.property('show');
    });
  });

  describe('Template', () => {
    // template specs
    // tip: use regex to ensure correct bindings are used e.g., {{  }}
    it('has show variable in template', () => {
      expect(BreadcrumbsTemplate).to.match(/{{\s?vm\.show\s?}}/g);
    });
  });

  describe('Component', () => {
      // component/directive specs
      let component = BreadcrumbsComponent;

      it('includes the intended template',() => {
        expect(component.template).to.equal(BreadcrumbsTemplate);
      });

      it('uses `controllerAs` syntax', () => {
        expect(component).to.have.property('controllerAs');
      });

      it('invokes the right controller', () => {
        expect(component.controller).to.equal(BreadcrumbsController);
      });
  });
});

在运行测试时-我得到了更多模块的测试,这些模块在spec.bundle.js中被引用-我收到错误:

  Breadcrumbs
    Component
      × invokes the right controller
        TypeError: Unable to get property 'equal' of undefined or null reference
        error properties: Object({ number: -2146823281 })
            at <Jasmine>
           at Anonymous function (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:50:8
<- spec.bundle.js:35968:7)
            at <Jasmine>

      × uses `controllerAs` syntax
        TypeError: Unable to get property 'have' of undefined or null reference
        error properties: Object({ number: -2146823281 })
            at <Jasmine>
           at Anonymous function (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:46:8
<- spec.bundle.js:35964:7)
            at <Jasmine>

      × includes the intended template
        TypeError: Unable to get property 'equal' of undefined or null reference
        error properties: Object({ number: -2146823281 })
            at <Jasmine>
           at Anonymous function (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:42:8
<- spec.bundle.js:35960:7)
            at <Jasmine>

    Template
      × has show variable in template
        TypeError: Unable to get property 'match' of undefined or null reference
        error properties: Object({ number: -2146823281 })
            at <Jasmine>
           at Anonymous function (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:33:6
<- spec.bundle.js:35951:7)
            at <Jasmine>

    Controller
      × has a show property
        TypeError: Unable to get property 'current' of undefined or null reference
        error properties: Object({ number: -2146823281 })
            at <Jasmine>
           at showBreadcrumbs (webpack:///client/app/common/breadcrumbs/breadcrumbs.controller.js:30
:4 <- spec.bundle.js:638:7)
           at updatePath (webpack:///client/app/common/breadcrumbs/breadcrumbs.controller.js:16:4 <-
 spec.bundle.js:622:7)
           at BreadcrumbsController (webpack:///client/app/common/breadcrumbs/breadcrumbs.controller
.js:10:4 <- spec.bundle.js:612:5)
           at makeController (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:13:6 <- s
pec.bundle.js:35931:7)
           at Anonymous function (webpack:///client/app/common/breadcrumbs/breadcrumbs.spec.js:24:6
<- spec.bundle.js:35942:7)
            at <Jasmine>

很明显,好像模块的控制器没有被实例化,是未定义的,未被调用,因为$state对象没有被注入。

但是当我尝试将uiRouter和Menu服务注入breadcrumbs.spec.js内时,像这样:

[...]
import uiRouter from 'angular-ui-router';
import Menu from '../menu/menu.js';
[...]
beforeEach(window.module(uiRouter));
beforeEach(window.module(Menu));
beforeEach(inject((_$rootScope_, uiRouter, Menu) => {
  $rootScope = _$rootScope_.$new();
  makeController = () => {
    return new BreadcrumbsController();
  };
}));

我也得到:

  

错误:[$ injector:unpr]未知提供程序:uiRouterProvider <-uiRouter`   错误。

我真的不知道问题出在哪里。

有什么想法吗?

0 个答案:

没有答案