首先,我有一个这样的控制器:
login.controller.js:
angular.module('app').controller('LoginController',
function($scope,UserService,$location) {
$scope.submit = function() {
UserService.login(email,password).then(function(data){
if(data.result=='success'){
$location.path('/home');
else{
$scope.loginError='Login failed';
}
},function(error){
$scope.loginError='Login failed';
});
};
和工厂服务:UserService.js
angular.module('app').factory('UserService', function($http,$q,CONST) {
login: function(username, password) {
var defer =$q.defer();
$http({
method:'POST',
url:CONST.baseUrl+'rest/login',
data:{
userName:username,
password:password
}
}).success(function(data,status,headers,config){
defer.resolve(data);
}).error(function(data){
defer.reject(data);
});
return defer.promise;
},
我的茉莉花测试就像这样:
describe('test the userService',function(){
beforeEach(module('app'))
var scope,LoginController,httpBackend;
beforeEach(inject(function(_$rootScope_,$controller,_UserService_,_$httpBackend_){
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
LoginController = $controller('LoginController',{
$scope:scope,
UserService:_UserService_
});
}));
it('when login post return success',function(){
httpBackend.expectPOST('rest/login',{
userName:'Jordan',
password:'password'
}).respond(200,{result:'success'});
spyOn(UserService,'login').and.callThrough();
scope.submit();
httpBackend.flush();
expect(UserService.login).toHaveBeenCalled();
expect(location.path()).toBe('/home');
});
afterEach(function(){
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
});
结果证明:
Chrome 43.0.2357 (Windows 7 0.0.0) test the userService when the login post retu
rn success FAILED
Expected spy login to have been called.
at Object.<anonymous> (C:/Users/IBM_ADMIN/desk/workspace/WaterFundWe
b/WebContent/test/unit/userService.js:28:29)
但我确信调用了login()函数,它怎么能来到这个
答案 0 :(得分:0)
首先,我重构了您的LoginController
和UserService
:
//I also created CONST factory and it just returns empty string as baseUrl,
//because I don't know what's the logic inside this factory in your code.
angular.module('app').factory('CONST', function() {
return {
baseUrl: ''
};
});
angular.module('app').factory('UserService', function($http, $q, CONST) {
//UserService should return object with login function.
//You've shown code for this factory with incorrect syntax.
return {
login: function (username, password) {
var defer = $q.defer();
$http({
method: 'POST',
url: CONST.baseUrl + 'rest/login',
data: {
userName: username,
password: password
}
}).success(function (data, status, headers, config) {
defer.resolve(data);
}).error(function (data) {
defer.reject(data);
});
return defer.promise;
}
};
});
angular.module('app').controller('LoginController', function($scope, UserService, $location) {
//Here you have to add parameters to $scope.submit function,
//because you're going to use it while calling UserService.login function
$scope.submit = function (email, password) {
UserService.login(email, password).then(
function (data) {
if (data.result == 'success') {
$location.path('/home');
} else {
$scope.loginError = 'Login failed';
}
},
function (error) {
$scope.loginError = 'Login failed';
});
};
});
重构后,我在测试中发现了一些语法错误。我正在通过我的评论和修正向您展示整个代码。
describe('test the userService',function() {
var scope, LoginController, httpBackend,
userService, //You should create variable for UserService to work with it further (creating spies and so on)
location; //You also need variable for $location service to check current path in your test
beforeEach(inject(function(_$rootScope_, $controller, UserService, _$httpBackend_, _$location_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
////Don't forget to initialize your 'new' variables
location = _$location_;
userService = UserService;
LoginController = $controller('LoginController', {
$scope:scope,
UserService: userService,
$location: location //Pass $location service to your LoginController
});
}));
it('when login post return success',function(){
httpBackend.expectPOST('rest/login',{
userName:'Jordan',
password:'password'
}).respond(200,{result:'success'});
spyOn(userService, 'login').and.callThrough();
//Here we pass parameters, which are needed for login function.
//You expect that POST request to rest/login url will be sent with 'Jordan' username and 'password' as password.
//So, we pass it to $scope.submit function
scope.submit('Jordan', 'password');
httpBackend.flush();
expect(userService.login).toHaveBeenCalled();
expect(location.path()).toBe('/home');
});
afterEach(function(){
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
});
现在您的测试通过了。
如果您有任何疑问或不适合您,请与我们联系。