2

I have a controller that initializes an object upon initialization of the controller, and would like to test that it was called with the specific params that it is actually called with.

I know that I can test that $scope.autoSaveObj has certain properties that would tell me that it in fact initialized, but how would I spy on the initialization event itself?

Essentially, I want to spy on new autoSaveObj just like I would a method.

The main reason I want to test and spy on the object contructor is so that my karma-coverage plugin will show those lines as covered. It won't show the lines as covered if I just test the state of $scope.autoSaveObject after the initialization.

App.controller('ItemCtrl',[ '$scope', function($scope){
  $scope.autoSaveObject = new autoSaveObj({
    obj: $scope.item,
    saveCallback: function() {
                  return $scope.saveItem();
                },
    errorCallback: null,
    saveValidation: $scope.validItem,
    delay: 2000
  });
}]);

1 Answer 1

2

My guess is the code example is of a partial controller, because properties in the $scope are used which are not initialized here.

Since autoSaveObj is not defined anywhere, I assumed it is a global function. Consider moving this to a service or factory instead.

The following example shows how to

  • mock autoSaveObj
  • verify the call parameters, and
  • verify that the created instance is actually an instance of the correct type.

angular.module('myApp', []).

controller('ItemCtrl', function($scope, $window) {
  // Use the injected $window object, so we don't rely on
  // the environment and it can be mocked easily.
  $scope.autoSaveObject = new $window.autoSaveObj({
    obj: $scope.item,
    saveCallback: function() {
      return $scope.saveItem();
    },
    errorCallback: null,
    saveValidation: $scope.validItem,
    delay: 2000
  });
});


describe('ItemCtrl', function() {
  var $controller;
  var $scope;
  var $window;
  var controller;

  beforeEach(module('myApp', function($provide) {
    $window = {
      // Create an actual function that can be spied on.
      // Using jasmine.createSpy won't allow to use it as a constructor.
      autoSaveObj: function autoSaveObj() {}
    };

    // Provide the mock $window.
    $provide.value('$window', $window);
  }));

  beforeEach(inject(function(_$controller_, $rootScope) {
    $controller = _$controller_;
    $scope = $rootScope.$new();
  }));

  it('should instantiate an autoSaveObj', function() {
    spyOn($window, 'autoSaveObj');
    // Initialize the controller in a function, so it is possible
    // to do preparations.
    initController();
    // Do function call expectations as you would normally.
    expect($window.autoSaveObj).toHaveBeenCalledWith(jasmine.objectContaining({
      saveCallback: jasmine.any(Function),
      delay: 2000
    }));
    // The autoSaveObject is an instance of autoSaveObj,
    // because spyOn was used, not jasmine.createSpy.
    expect($scope.autoSaveObject instanceof $window.autoSaveObj).toBe(true);
  });

  function initController() {
    controller = $controller('ItemCtrl', {
      $scope: $scope
    });
  }
});
<link href="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-mocks.js"></script>

Sign up to request clarification or add additional context in comments.

1 Comment

I forgot to inject autoSaveObject as a dependency, and yes it is a toned down look at the ctrl

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.