我正在尝试测试在服务上调用方法的控制器。 service方法返回一个promise,控制器在调用service方法后立即调用.then()
inline。我正在尝试使用sinon存根服务,并且Jasmine不断抛出错误,指出then
未定义且不是函数。
这是控制器:
var loginModalController = function ($scope, authenticationService) {
this.submit = submit;
function submit(user, password) {
$scope.email = user;
authenticationService.login(user, password)
.then(handleSuccessLogin, handleErrorLogin);
}
}
这是服务:
function authenticationService($http, $q, endPointService) {
var baseUri = endPointService.getApiEndpoint();
var service = {
getTermsAndConditions: getTermsAndConditions,
login: login,
acceptTerms: acceptTerms
};
return service;
function getTermsAndConditions() {
...
};
function login(user, password) {
var deferred = $q.defer();
$http({ method: 'POST', url: baseUri + '/api/tokens', data: { username: user, password: password } }).
success(function (data, status, headers, config) {
$http.defaults.headers.common.Authorization = 'Basic ' + data.EncryptedTokenId;
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
};
function acceptTerms() {
...
};
}
这是测试:
describe('loginModalController', function () {
var scope, loginModalController, authenticationServiceMock, localSaverServiceMock;
var loginInformationMock = { 'firstName': 'Testuser' };
beforeEach(function () {
module('clientAppModule');
inject(function ($rootScope, $controller, authenticationService, localSaverService) {
scope = $rootScope.$new();
authenticationServiceMock = sinon.stub(authenticationService)
.login.returns({ then: function () { return loginInformationMock } });
localSaverServiceMock = sinon.stub(localSaverService);
loginModalController = $controller('loginModalController', {
$scope: scope,
$state: {},
authenticationService: authenticationServiceMock,
errorCodes: {},
localSaverService: localSaverServiceMock
});
});
});
it('should login', function () {
loginModalController.submit("test", "test");
});
});
答案 0 :(得分:0)
我的代码有四个问题:
stub()
的返回值,而不仅仅是让它存根服务。$q
返回延迟的保证以匹配登录功能。$digest()
以获得在断言之前解决的延迟承诺。所以这是固定的测试代码:
beforeEach(module('clientAppModule'));
describe('loginModalController', function () {
var scope, authenticationService, localSaverService;
var loginInformationMock = { 'firstName': 'Testuser' };
beforeEach(inject(function ($injector, $rootScope, $controller, $q) {
scope = $rootScope.$new();
scope.$close = function () { };
authenticationService = $injector.get('authenticationService');
localSaverService = $injector.get('localSaverService');
spyOn(authenticationService, 'login').and.callFake(function () {
var deferred = $q.defer();
deferred.resolve(loginInformationMock);
return deferred.promise;
});
spyOn(localSaverService, 'saveLoginInformation').and.stub();
$controller('loginModalController', {
$scope: scope,
$rootScope: {},
$state: {},
authenticationService: authenticationService,
errorCodes: {},
localSaverService: localSaverService
});
}));
it('should call login on authenticationService', function () {
// Arrange
// Act
scope.submit("test", "test");
// Assert
expect(authenticationService.login).toHaveBeenCalled();
});
it('should save login info after successful login', function () {
// Arrange
// Act
scope.submit("test", "test");
scope.$digest();
// Assert
expect(localSaverService.saveLoginInformation).toHaveBeenCalled();
});
});