Javascript 角茉莉花';s spyOn对工厂的功能没有影响

Javascript 角茉莉花';s spyOn对工厂的功能没有影响,javascript,angularjs,jasmine,karma-runner,Javascript,Angularjs,Jasmine,Karma Runner,首先,我有一个这样的控制器: login.controller.js: angular.module('app').controller('LoginController', function($scope,UserService,$location) { $scope.submit = function() { UserService.login(email,password).then(function(data){

首先,我有一个这样的控制器:

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)
Chrome 43.0.2357(Windows 7 0.0.0)在登录后重试时测试用户服务
rn成功失败
预期已调用间谍登录名。
反对。(C:/Users/IBM_ADMIN/desk/workspace/WaterFundWe
b/WebContent/test/unit/userService.js:28:29)

但是我确信login()函数被调用了,它怎么会变成这样呢首先,我重构了你的
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();
    });
});
现在你的考试通过了


如果您有问题或它不适合您,请告诉我。

问题已解决!按照你的指导,我发现我没有为“UserService”创建变量。当我添加它时,测试通过了。你的代码确实帮了很多忙,非常感谢!