angularjs单元测试元素$ onInit绑定undefined

时间:2017-08-25 09:53:53

标签: angularjs unit-testing

成分

import template from './account.html';
import controller from './account.controller';
import './account.less';

const accountComponent = {
  bindings: {
    user: '<',
    onLogout: '&'
  },
  template,
  controller
};

export default accountComponent;

控制器

class AccountController {
  constructor() {}
  $onInit() {
    this.isVisibled = false;
    this.fullname = this.user.firstName + ' ' + this.user.lastName;
  }
  show() {
    this.isVisibled = !this.isVisibled;
  }
  logout() {
    this.onLogout();
  }
}

export default AccountController;

测试

import accountModule from './index';


describe('Account', () => {

  beforeEach(angular.mock.module(accountModule));

  let onLogoutSpy = jasmine.createSpy('onLogout');

  const bindings = {
    user: {
      "firstName" : "me",
      "lastName" : "you"
    },
    onLogout: onLogoutSpy
  };

  let controller,
    rootScope,
    scope;

  describe('Controller', () => {

      beforeEach(inject( ($injector) => {
        rootScope = $injector.get('$rootScope');
        scope = rootScope.$new();
        const $componentController = $injector.get('$componentController');
        controller = $componentController('appAccount',{$scope:scope},bindings);
        controller.$onInit();
      }));

      it('should be attached to the scope', () => {
        expect(scope.$ctrl).toBe(controller);
      });

      it('isVisibled should be false', () => {
        expect(controller.isVisibled).toBe(false);
      });

      it('fullname should be me you', () => {
        expect(controller.fullname).toEqual('me you');
      });

      it('isVisibled should be true', () => {
        controller.show();
        expect(controller.isVisibled).toBe(true);
      });

      it('should onLogout have been called', () => {
        controller.logout();
        expect(onLogoutSpy).toHaveBeenCalled();
      });

    });

  describe('Component', () => {

    let element,scope;

    beforeEach(inject(($rootScope, $compile) => {
      dump(bindings.user);
       scope = $rootScope.$new();
        const markup = `
          <app-account user="bindings.user"></app-account>
        `;
        element = angular.element(markup);
        element = $compile(element)(scope);
        let elementController = element.controller('app-account');
        scope.$digest();
        elementController.$onInit(); 

    }));

    it('xxx', () => {
      //dump(element);
      //const backendHeader = element.find('backend-header').eq(0);
      //expect(backendHeader).toBeDefined();
    });


  });
});

给我

1)xxx      帐户组件      TypeError:无法读取未定义的属性“firstName”

你能帮我解决一下吗?

2 个答案:

答案 0 :(得分:1)

我认为你应该写:

beforeEach(inject(($rootScope, $compile) => {
  scope = $rootScope.$new();
  scope.user = {
    firstName "me",
    lastName : "you"
 } 
 element = $compile(`<app-account user="user"></app-account>`)(scope);
 let elementController = element.controller('app-account');
 scope.$digest();
}));

您正在传递绑定对象的用户obj,它必须是范围的用户obj。

答案 1 :(得分:1)

您未在第二次测试中将bindings指定给范围

scope = $rootScope.$new();
scope.bindings = bindings;  // -------v
const markup = '<app-account user="bindings.user"></app-account>';