title: Angular testing controller using mock factory which returns promise
body: <p>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 &amp; 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.</p>
  
  <p>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.</p>
  
  <p>Angular Controller</p>
  
  <pre><code>    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(() =&gt; {
            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;
        };
  
      }
  </code></pre>
  
  <p>Angular Factory</p>
  
  <pre><code>  const dataService = ($q) =&gt; {
      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) =&gt; {
           //data looks like this: {totalSize: 3, done: true, records: [......]}
           work = data.records;
         });
      }
  
      function getTasks() {
        return queryWrapper(`SELECT Id,...`)
         .then((data) =&gt; {
           //data looks like this: {totalSize: 3, done: true, records: [......]}
           tasks = data.records;
         });
      }
  
      function addNumberOTasksToWork() {
        work.forEach((workItem) =&gt; {
          workItem.numberOfTasks = 0;
        });
        work.forEach((workItem) =&gt; {
          tasks.forEach((taskItem) =&gt; {
            if (taskItem.agf__Work__c === workItem.Id) {
              workItem.numberOfTasks++;
            }
          });
        });
      }
  
      function getState(){
        return {work,tasks};
      }
  
    };
  
    export {dataService};
  </code></pre>
  
  <p>Test file</p>
  
  <pre><code>  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_;
      }));
  
  
  
  
  
    });
  </code></pre>