0

I have the following code defined in my controller

(function() {
    'use strict';

    angular
    .module('bolt')
    .controller('PackdownController', PackdownController);

    PackdownController.$inject = ['$location', '$timeout', 'packdownService', 'modelTransformer', 'Packdown'];

    function PackdownController($location, $timeout, packdownService, modelTransformer, Packdown) {
        var vm = this;  

        vm.totalItemCount = 0;
        vm.completedItemCount = 0;
        vm.toDoItems = [];
        vm.completedItems = [];

        activatePackdown();

        function activatePackdown() {
            packdownService.GetAllTasks().then(function(data) {
                if(data !== undefined && data !== null) {
                    if(data.error.state) {
                            showError('Error retrieving tasks', 'Please try again. If the problem persists, contact your supervisor', 'Close', toggleErrorModal);
                    }
                    else {               
                        vm.totalItemCount = tasks.openItems + tasks.closeItems;
                        vm.completedItemCount = tasks.closeItems;
                        angular.forEach(tasks.bayTasks, function(value, key) {
                            if(value.status.description !== 'COMPLETED_THIS_CYCLE') {
                                var task = {
                                        deptNbr: value.department.number,
                                        bayName: value.aisle + '-' + value.bay,
                                        status: {
                                            code: value.status.code,
                                            description: value.status.description
                                        }
                                };
                                this.push(task);
                            }
                        }, vm.toDoItems);
                        angular.forEach(tasks.bayTasks, function(value, key) {
                            if(value.status.description === 'COMPLETED_THIS_CYCLE') {
                                var task = {
                                        deptNbr: value.department.number,
                                        bayName: value.aisle + '-' + value.bay,
                                    completedBy: value.completedSystemUserId,
                                        completedOn:  new Date(value.completedTimeStamp)
                                };
                                this.push(task);
                            }
                        }, vm.completedItems);
                    }
                }

            });


        }

    }
})();

activatePackdown is a private function, so I can't test it directly, but I can test the value(s) of public properties once the controller is created. However, since that function calls a service method (that returns a promise), I don't know how to test inside the .then statement. I have the following for my unit test:

describe('activatePackdown', function(){            
    it('should call GetAllTasks and then set completed/total counts', function(done) {
        var spy = sinon.spy(this.packdownService, 'GetAllTasks');

        var ctlr = $controller('PackdownController');
        expect(spy).toHaveBeenCalled();
    });
});

the .toHaveBeenCalled passes just fine, but everything I've tried to do to test the state of properties in the .then. For instance, the value of vm.totalItemCount. I know I don't actually want the GetAllTasks method to run, so I created the spy using sinon.spy, but I'm at a point now where I don't know what to do next. I've tried several different suggestions I've found on varying blogs, but nothing seemed to work. Any and all help is greatly appreciated

2 Answers 2

1

Using jasmine, I'd mock inject $q and $controller;

var deferred = $q.defer();
spyOn(Object, 'method').and.returnValue(deferred.promise);
controller.method(); //Calling your controller method

Then to test your success in then

 $scope.$apply(function () {
    deferred.resolve(<insert expected object>);
 });

To test your then when there's an error

$scope.$apply(function () {
   deferred.reject();
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for trying to help, however, since the controller isn't using $scope, that throws an error. Notice I am using an IIFE and using vm = this, as suggested by John Papa. all methods/properties are attached to vm, not $scope.
I follow john papa's style guide too. this is root scope am talking about, sorry i failed to mention. inject rootscope and do something like this: $scope = $rootScope.$new();
Ah yes, must be in a post-lunch coma. anyway, got it working. forgot that i had to inject $rootScope in the tests. Anyway, thanks got it working.
0

just for future reference, here's what my working test now looks like

it('should call GetAllTasks and then set completed/total counts', function() {
     var deferred = this.$q.defer();
     var stub = sinon.stub(this.packdownService, 'GetAllTasks').returns(deferred.promise);
     deferred.resolve(response);
     var ctlr = $controller('PackdownController');

     this.$timeout.flush();           
     expect(ctlr.totalItemCount).toEqual(4);
     this.$timeout.verifyNoPendingTasks();
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.