Reputation: 451
I'm running into problems using sinon to stub a factory while testing my controller. I'm using mocha, chai and sinon on top of angularjs.
Basically, I have a Classrooms factory that I'd like to stub and spy on, while I'm testing my controller.
Here's my controller code:
angular.module('app')
.controller('ClassroomsCtrl', function ($scope, Classrooms){
function init(){
$scope.classrooms = Classrooms.search();
}
init();
});
Here's my factory code:
angular.module('app').factory('Classrooms', ['$resource', function($resource) {
return $resource('/classrooms/:id', {
id: '@id'
},
{
search: {
method: 'GET',
url: '/classrooms/search',
isArray: true
}
});
});
And here's my controller unit test:
angular.module('MyAppMocks',[]).
factory('Classrooms', function(){
return {
search: sinon.stub()
}
});
describe('Controller: ClassroomsCtrl', function () {
var scope, Classrooms, controllerFactory, spy;
function createController() {
return controllerFactory('ClassroomsCtrl', {
$scope: scope,
Classrooms: Classrooms
});
}
// load the controller's module
beforeEach(module('app'));
beforeEach(module('MyAppMocks'));
beforeEach(inject(function($controller, $rootScope, _Classrooms_){
scope = $rootScope.$new();
Classrooms = _Classrooms_;
controllerFactory = $controller;
}));
it('should call Classrooms.search', function(){
createController();
expect(Classrooms.search).to.have.been.called();
});
});
When I run my spec, I'm getting this error:
✗ should call Classrooms.search
TypeError: '[object Object]' is not a function (evaluating 'expect(Classrooms.search).to.have.been.called()')
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/test/spec/controllers/classrooms.js:43
at callFn (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4338)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4331
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4728
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4819
at next (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4653)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4663
at next (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4601)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4625
at done (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4300)
at callFn (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4343)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4331
at next (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4626)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4625
at done (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4300)
at callFn (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4343)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4331
at next (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4626)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4625
at done (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4300)
at callFn (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4343)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4331
at next (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4626)
at /Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:4630
at timeslice (/Users/tc/Documents/code/sandbox/edumatcher/ng-app/node_modules/mocha/mocha.js:5763)
It seems like I have the stubbed Classrooms factory injected right, but something's not working with sinon. Any advice would be greatly appreciated. Thanks
Upvotes: 0
Views: 1344
Reputation: 90
I don't think this is it but what if you change
expect(Classrooms.search).to.have.been.called();
to
expect(Classrooms.search).to.have.been.called;
Noticed when using chai (BDD style, fwiw) that those weren't functions, just properties. Silly BDD. :)
Upvotes: 3