mercredi 25 février 2015

Unit testing a directive - Override data by Controller or Service

I'm trying to understand how to unit test my directive in my situation below.


Basically I'm trying to unit test a directive which has a controller. On the loading of this directive the controller makes a http request by a service which brings some data to the controller again then provides this data to the directive view.


On the scenario below in my understanding I should do:



  • A $httpBackend to avoid an exception when the http request is done;

  • Populate the fake data to be able to unit test the directive with diff behaviors

  • Compile the directive


What I've been trying so far, as you can see, is override the Service with the fake data. What I could not make work so far.


Some doubts come up now.


As you can see in my Controller. I'm providing the whole Service to the view:



$scope.ItemsDataservice = ItemsDataservice;



What makes me believe that my approach to override the Service should work.


My question:


On scenario below I understand that I could override the Service to manipulate the data or even override the controller to manipulate the data by scope.


What's the right thing to do here? Am I understand wrong? Am I mixing the unit tests?


In my current unit test code, when I'm applying the fake data(or not), is not make any difference:



ItemsDataservice.items = DATARESULT;


ItemsDataservice.items = null;



Controller:



angular.module('app')
.controller('ItemsCtrl', function ($scope, $log, ItemsDataservice) {

$scope.ItemsDataservice = ItemsDataservice;
$scope.ItemsDataservice.items = null;

$scope.loadItems = function() {

var items = [];

ItemsDataservice.getItems().then(function(resp) {

if (resp.success != 'false') {

for (resp.something ... ) {
items.push({ ... });
};

ItemsDataservice.items = items;

};

}, function(e) {
$log.error('Error', e);
});
};

$scope.loadItems();

});


Service:



angular.module('app')
.service('ItemsDataservice', function ItemsDataservice($q, $http) {

ItemsDataservice.getItems = function() {

var d = $q.defer();
var deffered = $q.defer();
var url = 'http://some-url?someparameters=xxx'

$http.get(url)
.success(function (d) {
deffered.resolve(d);
});

return deffered.promise;

};

return ItemsDataservice;

});


Directive:



angular.module('app')
.directive('items', function () {
return {
templateUrl: '/items.html',
restrict: 'A',
replace: true,
controller: 'ItemsCtrl'
};
});


Unit testing directive:



ddescribe('Directive: Items', function () {

var element, scope, _ItemsDataservice_, requestHandler, httpBackend;
var URL = 'http://some-url?someparameters=xxx';
var DATARESULT = [{ ... }];

// load the directive's module
beforeEach(module('app'));
beforeEach(module('Templates')); // setup in karma to get template from .html

beforeEach(inject(function ($rootScope, ItemsDataservice) {

httpBackend = $httpBackend;
scope = $rootScope.$new();
_ItemsDataservice_ = ItemsDataservice;

requestHandler = httpBackend.when('GET', URL).respond(200, 'ok');

}));

afterEach(function() {
//httpBackend.verifyNoOutstandingExpectation();
//httpBackend.verifyNoOutstandingRequest();
});

it('Show "No Items available" when empty result', inject(function ($compile) {

_ItemsDataservice_.items = null;

element = angular.element('<div data-items></div>');
element = $compile(element)(scope);
scope.$digest();

element = $(element);
expect(element.find('.msg_noresult').length).toBe(1);

}));

it('Should not show "No Items available" when data available ', inject(function ($compile) {

_ItemsDataservice_.items = DATARESULT;

element = angular.element('<div data-items></div>');
element = $compile(element)(scope);
scope.$digest();

element = $(element);
expect(element.find('.msg_noresult').length).toBe(0);

}));

});

Aucun commentaire:

Enregistrer un commentaire