mercredi 3 février 2016

Angular, Redux, ES6, Unit Testing Controllers

Our Angular project moved to ES6 and Reduxjs, and now I am struggling to get controller unit tests working. Specifically, I cant seem to mock correctly when it comes to the class constructor. From what i have researched, i cant spyOn an ES6 class constructor, so i need to mock its dependencies and also accommodate the binding to lexical 'this' that ngRedux.connect() facilitates.

My test makes it to the connect function in the constructor, and then gives me the error: "'connect' is not a function"

I think i may have several things wrong here. If i comment out the connect line in the constructor, it'll get to my runOnLoad function and the error will tell me that fromMyActions isnt a function. this is because the redux connect function binds the actions to 'this', so given these issues, I take it I cant mock redux unless i provide its implementation. any advice? I am relatively new to angular as well - and my weakest area is unit testing and DI.

Here is my module and controller:

export const myControllerModule = angular.module('my-controller-module',[]);

export class MyController {

constructor($ngRedux, $scope) {
'ngInject';

  this.ngRedux = $ngRedux;
  const unsubscribe = this.ngRedux.connect(this.mapState.bind(this), myActions)(this);
  $scope.$on('$destroy', unsubscribe);
  this.runOnLoad();
}

mapState(state) {
  return {};
}

runOnLoad() {
   this.fromMyActions(this.prop);
  }
}

myControllerModule 
  .controller(controllerId, MyController
  .directive('myDirective', () => {
    return {
      restrict: 'E',
      controllerAs: 'vm',
      controller: controllerId,
      templateUrl: htmltemplate
      bindToController: true,
      scope: {
        data: '=',
        person: '='
      }
    };
  });

export default myControllerModule.name;

and my test:

import {myControllerModule,MyController} from './myController';
import 'angular-mocks/angular-mocks';

describe('test', () => {

  let controller, scope;

  beforeEach(function() {

let reduxFuncs = {
  connect: function(){}
}

angular.mock.module('my-controller-module', function ($provide) {
  $provide.constant('$ngRedux',reduxFuncs);
});

angular.mock.inject(function (_$ngRedux_, _$controller_, _$rootScope_) {
  scope = _$rootScope_.$new();
  redux = _$ngRedux_;

  var scopeData = {
    data : {"test":"stuff"},
    person : {"name":"thatDude"}
  } ;
        scope.$digest();

        controller = _$controller_(MyController, {
        $scope: scope,
        $ngRedux: redux
      }, scopeData);
    });

  });
});

Aucun commentaire:

Enregistrer un commentaire