Tibor Nagy Tibor Nagy - 12 days ago 5
AngularJS Question

'undefined is not an object' in karma/jasmine unit test

I have the following simple unit test:

describe('SyncController', function() {
var controller,
deferredRecount,
pouchdbServiceMock;

beforeEach(module('inspector'));

beforeEach(inject(function($controller, $q, $scope) {
deferredRecount = $q.defer();

pouchdbServiceMock = {
getRecordCounts: jasmine.createSpy('getRecordCounts spy').and.returnValue(deferredRecount.promise)
};

controller = $controller('SyncController', {
'$scope': $scope,
'pouchdbService': pouchdbServiceMock
});
}));

beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
controller.recount();
}));

describe('recount', function() {
it('should call getRecordCounts on pouchdbService', function() {
expect(pouchdbServiceMock.getRecordCounts).toHaveBeenCalled();
});
});
});


Calling
pouchdbServiceMock.getRecordCounts
in the last
describe
block generates an error:

TypeError: undefined is not an object (evaluating 'pouchdbServiceMock.getRecordCounts') in unit-tests/sync.controller.tests.js (line 29)


However
pouchdbServiceMock
is assigned in the second
beforeEach
block. What is wrong?

Answer

The problem was, that the second beforeEach block had an error:

Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope

So it did not initialized the variable pouchdbServiceMock. I rewrote the block a little bit:

  beforeEach(inject(function($controller, $q, $rootScope) {
    deferredRecount = $q.defer();
    scope = $rootScope.$new();

    pouchdbServiceMock = {
      getRecordCounts: jasmine.createSpy('getRecordCounts spy').and.returnValue(deferredRecount.promise)
    };

    controller = $controller('inspector.SyncController', {
      '$scope': scope,
      'pouchdbService': pouchdbServiceMock
    });
  }));

This solved the problem.

Comments