Angular testing controller using mock factory which returns promise

113 Views Asked by At

I'm trying to test an Angular controller and mock a factory so that I can use it within this same test. I'm fairly new to Angular testing & have been having trouble figuring out how to this. My factory, doesn't use the $http rather the $q service, returns a promise. I'm also unsure of what to put inside my mock factory given that the factory's function calls return a promise.

My end goal is to call my mock factory from my controller and then check the two arrays in my controller for the data which is supposed to populate them. If you have any tips for restructuring my tests for testability, please do give feedback.

Angular Controller

    export class workListController {
      constructor(dataService, $q) {
        this.$q = $q;
        this.work = [];
        this.tasks = [];
        this.dataService = dataService;
        this.setup();
      }

      setup() {
        this.$q.all([this.dataService.getWorkItems(), this.dataService.getTasks()])
        .then(() => {
          this.work = this.dataService.getState().work;
          this.tasks = this.dataService.getState().tasks;
          this.dataService.addNumberOTasksToWork();
        });
      }

      tasksForWork(workId) {
        var workTasks = [];
        for (let task of this.tasks) {
          if (task.agf__Work__c === workId) {
            workTasks.push(task);
          }
        }
        return workTasks;
      };

    }

Angular Factory

  const dataService = ($q) => {
    let work = [];
    let tasks = [];
    let connection = new Connection{/**/};

    return { getWorkItems, getTasks, addNumberOTasksToWork, getState};
    function queryWrapper(query) {
      var deferred = $q.defer();
      connection.query(query)
        .then(function(result) {
          deferred.resolve(result);
        }, function(error) {
          deferred.reject(error);
        });

      return deferred.promise;
    }


    function getWorkItems() {
      return queryWrapper(`SELECT Id, ......`)
       .then((data) => {
         //data looks like this: {totalSize: 3, done: true, records: [......]}
         work = data.records;
       });
    }

    function getTasks() {
      return queryWrapper(`SELECT Id,...`)
       .then((data) => {
         //data looks like this: {totalSize: 3, done: true, records: [......]}
         tasks = data.records;
       });
    }

    function addNumberOTasksToWork() {
      work.forEach((workItem) => {
        workItem.numberOfTasks = 0;
      });
      work.forEach((workItem) => {
        tasks.forEach((taskItem) => {
          if (taskItem.agf__Work__c === workItem.Id) {
            workItem.numberOfTasks++;
          }
        });
      });
    }

    function getState(){
      return {work,tasks};
    }

  };

  export {dataService};

Test file

  import {workList} from './work-list.module.js';
  import {workListDirective} from './work-list.directive.js';
  import template from './work-list.html';
  import {workListController} from './work-list.controller.js';

  describe('AA_TaskBoard -  workList', function () {
    let $scope;
    let $controller;
    let $httpBackend;
    let mockDataService;

    beforeEach(angular.mock.module(workList.name));
    //trying to mock factory
    beforeEach(angular.mock.module(function($provide) {
      $provide.value('dataService', mockDataService);
      mockDataService = {
        getWorkItems: function(){
          //this should return a promise, but unsure of what to put here
          return {

          };
        },
        getTasks: function(){
          return {

          };
        }
      };

    }));


    beforeEach(inject(function(_$rootScope_, _$controller_, _$httpBackend_) {
      $rootScope = _$rootScope_;
      $controller = _$controller_;
      $httpBackend = _$httpBackend_;
    }));





  });
0

There are 0 best solutions below