harsh
harsh

Reputation: 247

Unit Testing a Controller with specific syntax

Whenever, I am testing a controller and have something like this in it.

$scope.isSomething = function (Item) {
      return ItemCollection.someItem(Item.attachedItem);
    };

giving error on karma console:

TypeError: undefined is not an object (evaluating 'Item.attachedItem')

I am simply calling the function from the test file like this:

scope.isSomething();

I need to mock the Item.attachedItem or I am missing something here.. Please Explain in details as this is happening in multiple files.. thanks in advance

Also, for this type of code

   .controller('itemCtrl', function (itemCollection) {
        var vm = this;
        this.itemCollection= itemCollection;
     itemCollection.someItem().then(function (Item) {
          vm.pageUrl = Item.pageUrl;
          vm.Item= Item.someItems;
        });
    });

Also, this is also part of the code for more broad view here it gives Item.pageUrl is not a object error

Upvotes: 1

Views: 63

Answers (3)

gmuraleekrishna
gmuraleekrishna

Reputation: 3431

Refer angular unit testing docs

The ItemCollection being a service, you could inject a mock while initialising a controller using

    var ItemCollection, ItemCrtl;
    beforeEach(inject(function($controller, $rootScope) {
        $scope = $rootScope.$new();
        ItemCollection = jasmine.createSpyObj('ItemCollection', ['someItem']);

        ItemCrtl = $controller('ItemCtrl', {
            $scope: scope,
            ItemCollection: ItemCollection
        });
    });

For Item, the method isSomething should take care of checking if Item is undefined before doing Item.attachedItem

Testing an aync block is tricky. someItem returns a promise. $q an angular service to which can be used create async functions while testing. We need to resolve the deferred object to test the async task.

    var ItemCollection, ItemCrtl, deferedObj;
    beforeEach(inject(function($controller, $rootScope, $q) {
        $scope = $rootScope.$new();
        deferedObj = $q.defer();
        ItemCollection = jasmine.createSpyObj('ItemCollection', ['someItem']);
        ItemCollection.someItem.andReturn(deferedObj.promise);

        ItemCtrl = $controller('ItemCtrl', {
            $scope: scope,
            ItemCollection: ItemCollection
        });
    });

    it('sets page url', function() {
     deferedObj.resolve({ pageUrl: 'http://url', someItems: [1,2,3] });
     scope.$apply();
     expect(ItemCtrl.pageUrl).toEqual('http://url');
    });

Upvotes: 2

Prasanna Rkv
Prasanna Rkv

Reputation: 419

$scope.isSomething = function (Item) {
  if(!Item.attachedItem){
        Item.attachedItem=YOUR_MOCK_VALUE;
  }
  return ItemCollection.someItem(Item.attachedItem);
};

Upvotes: 0

Pavan Teja
Pavan Teja

Reputation: 3202

you have to use mock Item data in test like this (assuming attachedItem value is boolean)

    var item={attachedItem:true}
    scope.isSomething(item)

Upvotes: 0

Related Questions