如何测试具有硬编码AJAX调用的指令?

时间:2015-09-02 10:42:15

标签: angularjs jasmine

我不确定如何测试此指令,有人会提供代码段吗?这是我的指示:

.directive('checkUnique', ['$http', function($http) {
    return {
        require: 'ngModel',
        link: function(scope, ele, attrs, c) {
            var origonalVal = attrs.ignoreUniqueValue;

            scope.$watch(attrs.ngModel, function() {
                var toURL= 'to/an/api';                
                $http({
                    method: 'GET',
                    url: toURL
                }).success(function(isUnique,status,headers,cfg) {
                    var iu = isUnique == 'true' ? true : false;
                    c.$setValidity('unique', iu);
                }).error(function(data,status,headers,cfg) {
                    c.$setValidity('unique', false);
                });
            });
        }
    }
}])

1 个答案:

答案 0 :(得分:2)

首先,在指令的link函数中使用此逻辑并不是一个好主意。这里是我将使用的设置(简化和未测试):

var myApp = angular.module('myApp', []);

myApp.factory('dataService', function($q, $http){
    return {
        isUnique: function(){
            return $q(function(resolve, reject){
                $http({
                    method: 'GET',
                    url: 'to/an/api'
                }).success(function(isUnique,status,headers,cfg) {
                    resolve(isUnique == 'true');
                }).error(function(data,status,headers,cfg) {
                    reject();
                });
            }); 
        }
    }
});

myApp.controller('UniqueController', function($scope, dataService){
    var vm = this,
        unWatchNgModel;

    unWatchNgModel = $scope.$watch('ngModel', onNgModelChanged);
    $scope.$on('$destroy', onDestroy);

    function onNgModelChanged(){
        dataService.isUnique().then(function(unique){
            vm.ngModelCtrl.$setValidity('unique', unique);
        });
    }       

    function onDestroy(){
        unWatchNgModel();
    }
});

myApp.directive('checkUnique', ['$http', function($http) {
    return {
        require: ['checkUnique', 'ngModel'],
        scope: {
            ngModel: '='
        }
        controller: 'UniqueController',
        controllerAs: 'unique',
        bindToController: true
        link: link
    };

     function link(scope, ele, attrs, ctrls) {
        var checkUniqueCtrl = ctrls[0],
            ngModelCtrl = ctrls[1];

        checkUniqueCtrl.ngModelCtrl = ngModelCtrl;
    }
}]);

要测试此(ajax部分),请使用如下设置:

// Note that you need the 'ngMockE2E' module to have access to the $httpBackend service.
describe('dataService', function() {
    'use strict';

    var dataService;

    beforeEach(function() {

        module('myApp');

        inject(function($injector) {
            dataService = $injector.get('dataService');
            $httpBackend = $injector.get('$httpBackend');
        });
    });

    describe('isUnique', function() {

        it('should return true if the API returns true as value.', function() {
            // Setup
            var successSpy = jasmine.createSpy('success');

            $httpBackend.expectGET(endpoint).respond(200, 'true');

            // Execute
            dataService.isUnique(successSpy);
            $httpBackend.flush();

            // Test
            expect(successSpy).toHaveBeenCalledWith(true);
        });

        it('should return false if the API does not return true as value.', function() {
            // Setup
            var successSpy = jasmine.createSpy('success');

            $httpBackend.expectGET(endpoint).respond(200, 'bogus');

            // Execute
            dataService.isUnique(successSpy);
            $httpBackend.flush();

            // Test
            expect(successSpy).toHaveBeenCalledWith(false);
        });
    });

});