问题
I have an Angular directive that, when attached to an <input>
, waits one second after user input before querying an endpoint with $http. In short, it's meant to check username uniqueness.
It looks like this:
.directive('sgValidUsername', ['$http', function(http) {
var waitTimer;
var checkIfUserExists = function(e, ctrl) {
http.get('/publicapi/users/' + e.target.value + '/exists')
.success(function(data) {
ctrl.$setValidity('unique', !data.exists);
});
};
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
element.on('blur keyup', function(e) {
if (e.target.value) {
clearInterval(waitTimer);
waitTimer = setTimeout(function() {
checkIfUserExists(e, ctrl);
}, 1000);
}
});
}
};
}]);
I'm trying my best to write a good comprehensive Jasmine unit test suite, but it's not working out because I couldn't find an appropriate example to learn from. I end up reconstructing the directive in test form rather than actually testing the directive. Also, I get a 'no pending request to flush' error.
Any suggestions for the below?
describe('SignupForm directives', function () {
var form, // el to which directive is applied
$scope,
$httpBackend, // $http mock
usernameExistsHandler;
beforeEach(function() {
module('signupform.directives');
});
beforeEach(function() {
inject(function ($injector, $rootScope, $compile, $q, $timeout) {
$scope = $rootScope;
$httpBackend = $injector.get('$httpBackend');
usernameExistsHandler = $httpBackend.whenGET(/\/publicapi\/users\/.+?\/exists/);
var el = angular.element('<form name="form"><input type="text" name="username" ng-model="user.username" sg-username-is-valid /></form>');
$scope.user = { username: null };
$compile(el)($scope);
form = $scope.form;
});
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should invalidate with existing usernames', function() {
form.username.$setViewValue('username_in_use');
$scope.$digest();
expect($scope.user.username).toEqual('username_in_use');
usernameExistsHandler.respond('200', { exists: true });
$httpBackend.expectGET('/publicapi/users/' + $scope.user.username + '/exists/');
$httpBackend.flush();
expect(form.username.$valid).toBe(false);
});
来源:https://stackoverflow.com/questions/26478319/unit-testing-angular-directive-with-http