Reputation: 1147
I have a controller that has a callback inside:
angular.module('controllers').controller('headerController', headerController);
function headerController(headerService) {
var self = this;
headerService.getHeaderContentData()
.then(function(response) {
self.contentData = response.content;
});
}
My problem is that I need to check the value of contentData
in an unit test. The idea is when I call expect(ctrl.contentData).to.be.defined
passes the test, but the value of ctrl.contentData
is undefined
. Is there a way to test this behavior (test the self.contentData when the callback occurs)?
Current unit test:
describe("controller", function() {
var controller, $httpBackend;
beforeEach(angular.mock.inject(function($injector, _$httpBackend_){
var $controller = $injector.get('$controller');
$httpBackend = _$httpBackend_;
var $scope = {};
$httpBackend.when('GET', '/data/header.content.json')
.respond(require('../../mock-data/header.content.json'));
var controller = $controller('headerController', { $scope: $scope });
$httpBackend.flush();
}));
it("should have contentData property populated", function() {
expect(controller.contentData).to.exist; // <- here fails: current value is undefined
});
});
My unit testing framework is jasmine
Upvotes: 1
Views: 1470
Reputation: 1797
Since your controller doesn't use $hhtp
, there is no reason to handle it in the test. The proper way to test your headerController
is to mock your headerService
.
Mock a service:
beforeEach(module(function($provide) {
mockService = jasmine.createSpyObj('headerService', ['getHeaderContentData']);
$provide.value('headerService', mockService);
}));
beforeEach(inject(function($controller) {
ctrl = $controller('headerController');
}));
Now, you need to mock getHeaderContentData()
to return a promise - use $q.
Mock service method:
it('should change after promise resolved', inject(function($q, $rootScope) {
//create promise
deferred = $q.defer();
//mock service response (foc controller's constructor)
mockService.getHeaderContentData.and.returnValue(deferred.promise);
//call init()
ctrl.init();
expect(ctrl.contentData).toBeNull();
deferred.resolve('Hello World');
//not yet...
expect(ctrl.contentData).toBeNull();
//from angular $q dosumentation:
//"it's important to know that the resolution of promises is tied to the digest cycle"
$rootScope.$apply();
//now!
expect(ctrl.contentData).toBe('Hello World');
}));
see jsFiddle
Upvotes: 2