Jasmine 如何设置间谍的响应
Jasmine how do I set the response of a spy
我的 Angular.js 控制器中有以下内容
function alreadyRegistered() {
if(reg.regForm.email.$valid){
console.log('this is logged in my console.');
authFactory.doesUserExist(reg.user)
.then(function(response){
console.log('this line if never hit');
if(response) {
reg.regForm.email.$setValidity('userExists', false);
} else {
reg.regForm.email.$setValidity('userExists', true);
}
})
.catch(function(err){
reg.error = err;
});
} else {
reg.regForm.email.$setValidity('userExists', true); // Remove userExists validation error.
}
};
我想通过将 .then() 内的响应设置为 true 或 false 来测试验证是否正常工作。但是我无法让我的测试进入 .then().
这是我的测试:
describe('Registration Controller Tests', function() {
var $controller, $scope, defer, doesUserExistSpy, authFactory, Registration,
beforeEach(module('enigma'));
beforeEach(inject(function (_$controller_, _$rootScope_, $q, $injector) {
$controller = _$controller_;
$scope = _$rootScope_;
defer = $q.defer();
// Create spies
doesUserExistSpy = jasmine.createSpy('doesUserExist').and.returnValue(defer.promise);
authFactory = {
register: registerSpy,
doesUserExist: doesUserExistSpy
};
// Init register controller with mocked services
Registration = $controller('Registration', {
$scope: $scope,
authFactory: authFactory,
$state: $state
});
// digest to update controller with services and scope
$scope.$digest();
}));
describe('check email field validity', function () {
var element, regForm;
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
element = angular.element(
'<form name="regForm">' +
'<input type="email" ng-model="test.email" name="email" value="bwayne@wayneenterprise.com" />' +
'</form>'
);
$compile(element)($scope);
regForm = $scope.regForm;
}));
it('should set regForm.email.$error.userExists to true if /doesUserExist returns true', function () {
$httpBackend.whenPOST('/doesUserExist').respond(defer.resolve(true)); // I'm trying to set the value for 'response' in the .then() for the controller.
Registration.alreadyRegistered();
$scope.$digest();
expect(regForm.email.$error.userExists).toEqual(true);
});
});
});
这是我的 authFactory 代码:
angular
.module('enigma.authFactory', [])
.factory('authFactory', authFactory);
authFactory.$inject = ['$http', '$q'];
function authFactory($window, $http, $q, sessionStorageFactory){
var auth = {
doesUserExist: doesUserExist
};
return auth;
function doesUserExist(email){
var defered = $q.defer();
$http.post('/app/doesUserExist', email)
.success(function(data){
if(data.message !== 'user exists'){
defered.resolve(false);
} else {
defered.resolve(true);
}
});
return defered.promise;
}
}
鉴于您完全模拟了您的 authFactory
服务,因此您无需触摸 $httpBackend
。只需解析您的模拟返回的 defer
对象。例如
it('should set regForm.email.$error.userExists to true if /doesUserExist returns true', function () {
Registration.alreadyRegistered();
expect(doesUserExistSpy).toHaveBeenCalled();
defer.resolve(true);
$scope.$apply();
expect(regForm.email.$error.userExists).toEqual(true);
});
我的 Angular.js 控制器中有以下内容
function alreadyRegistered() {
if(reg.regForm.email.$valid){
console.log('this is logged in my console.');
authFactory.doesUserExist(reg.user)
.then(function(response){
console.log('this line if never hit');
if(response) {
reg.regForm.email.$setValidity('userExists', false);
} else {
reg.regForm.email.$setValidity('userExists', true);
}
})
.catch(function(err){
reg.error = err;
});
} else {
reg.regForm.email.$setValidity('userExists', true); // Remove userExists validation error.
}
};
我想通过将 .then() 内的响应设置为 true 或 false 来测试验证是否正常工作。但是我无法让我的测试进入 .then().
这是我的测试:
describe('Registration Controller Tests', function() {
var $controller, $scope, defer, doesUserExistSpy, authFactory, Registration,
beforeEach(module('enigma'));
beforeEach(inject(function (_$controller_, _$rootScope_, $q, $injector) {
$controller = _$controller_;
$scope = _$rootScope_;
defer = $q.defer();
// Create spies
doesUserExistSpy = jasmine.createSpy('doesUserExist').and.returnValue(defer.promise);
authFactory = {
register: registerSpy,
doesUserExist: doesUserExistSpy
};
// Init register controller with mocked services
Registration = $controller('Registration', {
$scope: $scope,
authFactory: authFactory,
$state: $state
});
// digest to update controller with services and scope
$scope.$digest();
}));
describe('check email field validity', function () {
var element, regForm;
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
element = angular.element(
'<form name="regForm">' +
'<input type="email" ng-model="test.email" name="email" value="bwayne@wayneenterprise.com" />' +
'</form>'
);
$compile(element)($scope);
regForm = $scope.regForm;
}));
it('should set regForm.email.$error.userExists to true if /doesUserExist returns true', function () {
$httpBackend.whenPOST('/doesUserExist').respond(defer.resolve(true)); // I'm trying to set the value for 'response' in the .then() for the controller.
Registration.alreadyRegistered();
$scope.$digest();
expect(regForm.email.$error.userExists).toEqual(true);
});
});
});
这是我的 authFactory 代码:
angular
.module('enigma.authFactory', [])
.factory('authFactory', authFactory);
authFactory.$inject = ['$http', '$q'];
function authFactory($window, $http, $q, sessionStorageFactory){
var auth = {
doesUserExist: doesUserExist
};
return auth;
function doesUserExist(email){
var defered = $q.defer();
$http.post('/app/doesUserExist', email)
.success(function(data){
if(data.message !== 'user exists'){
defered.resolve(false);
} else {
defered.resolve(true);
}
});
return defered.promise;
}
}
鉴于您完全模拟了您的 authFactory
服务,因此您无需触摸 $httpBackend
。只需解析您的模拟返回的 defer
对象。例如
it('should set regForm.email.$error.userExists to true if /doesUserExist returns true', function () {
Registration.alreadyRegistered();
expect(doesUserExistSpy).toHaveBeenCalled();
defer.resolve(true);
$scope.$apply();
expect(regForm.email.$error.userExists).toEqual(true);
});