Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在karma jasmine中为AngularJS单元测试编写mock_Angularjs_Unit Testing_Jasmine_Karma Jasmine - Fatal编程技术网

如何在karma jasmine中为AngularJS单元测试编写mock

如何在karma jasmine中为AngularJS单元测试编写mock,angularjs,unit-testing,jasmine,karma-jasmine,Angularjs,Unit Testing,Jasmine,Karma Jasmine,我必须对我的控制器进行单元测试。首先,我必须为我的服务创建mock 这是我的服务: angular.module("demo-app") .factory("empService",function($http){ var empService={}; empService.getAllEmployees=function(){ return $http.get("http://localhost:3000/api/employees"); }

我必须对我的控制器进行单元测试。首先,我必须为我的服务创建mock

这是我的服务:

angular.module("demo-app")
.factory("empService",function($http){

    var empService={};
    empService.getAllEmployees=function(){
        return $http.get("http://localhost:3000/api/employees");
    }

    empService.postEmployee=function(emp){
        return $http.post("http://localhost:3000/api/employees",emp);
    }

    empService.getEmployee=function(id){
        return $http.get("http://localhost:3000/api/employees/"+id)
    }

    empService.putEmployee=function(emp){
        return $http.put("http://localhost:3000/api/employees/"+emp._id,emp)
    }

    empService.deleteEmployee=function(id){
        return $http.delete("http://localhost:3000/api/employees/"+id);
    }

    empService.findEmployee=function(emp){
        return $http.post("http://localhost:3000/api/employees/search",emp);
    }

    return empService;
})
下面是控制器中的findData()方法,我将对其进行测试:

$scope.findData=function(){
    $scope.loadingEmployee=true;
    var emp={};
    listProp=Object.getOwnPropertyNames($scope.searchEmployee);
    for(index in listProp){
        if($scope.searchEmployee[listProp[index]]!=""){
            emp[listProp[index]]=$scope.searchEmployee[listProp[index]];
        }
    }
    console.log(emp);
    empService.findEmployee(emp).then(function(data){   
        $scope.allEmployees=data.data;
        console.log(data.data);
        $scope.loadingEmployee=false;
    });
}
如何模拟empService.findeEmployee(emp)方法,以便测试findData()方法

我的spec.js测试文件,模拟我的服务方法。这是:

beforeEach(function(){
    var emp={"name":"sanjit"};
    fakeService={
        getAllEmployees:function(emp){
            def=q.defer();
            def.resolve({data:[{"name":"sanjit"},{'name':'ssss'}]});
            return def.promise;
        },
        findEmployee:function(emp){
            var def=q.defer();
            def.resolve({data:[{"name":"sanjit"}]});
            console.log("working");
            return def.promise;
        }
    };
    spyOn(fakeService,'findEmployee').and.callThrough();
    fakeService.findEmployee(emp);
});
beforeEach(angular.mock.inject(function($rootScope,$controller,$injector,$q){
    httpBackend=$injector.get('$httpBackend');
    scope=$rootScope.$new();
    q=$q;
    ctrl=$controller('adminEmployeeCtrl',{$scope:scope,empService:fakeService});
})); 

it('findData test',function(){
    scope.$apply();
    scope.findData();
    expect(scope.loadingEmployee).toEqual(false);
})
但我还有一个错误:

 Error: Unexpected request: GET dashboard/views/dashboard-new.html
 No more request expected

但我没叫它。请帮助我

您可能没有手动调用
GET dashboard/views/dashboard new.html
,但是
$scope.$apply()
可能会以某种方式触发它,您除了处理它之外什么都做不了

您可以这样做来处理它:(在使用
\u$httpBackend\u
注入它并在
之前将其分配给
$httpBackend


在angularjs中测试控制器时,最重要的规则之一是您不需要创建reall http请求,只需模拟控制器使用的服务中的函数即可。因此,您需要监视它们并调用fake函数来返回正确的值。让我们监视其中一个

/**
 * @description Tests for adminEmployeeCtrl controller
 */
(function () {

    "use strict";

    describe('Controller: adminEmployeeCtrl ', function () {

        /* jshint -W109 */
        var $q, $scope, $controller;
        var empService;
        var errorResponse = 'Not found';


        var employeesResponse = [
            {id:1,name:'mohammed' },
            {id:2,name:'ramadan' }
        ];

        beforeEach(module(
            'loadRequiredModules'
        ));

        beforeEach(inject(function (_$q_,
                                    _$controller_,
                                    _$rootScope_,
                                    _empService_) {
            $q = _$q_;
            $controller = _$controller_;
            $scope = _$rootScope_.$new();
            empService = _empService_;
        }));

        function successSpies(){

            spyOn(empService, 'findEmployee').and.callFake(function () {
                var deferred = $q.defer();
                deferred.resolve(employeesResponse);
                return deferred.promise;
                // shortcut can be one line
                // return $q.resolve(employeesResponse);
            });
        }

        function rejectedSpies(){
            spyOn(empService, 'findEmployee').and.callFake(function () {
                var deferred = $q.defer();
                deferred.reject(errorResponse);
                return deferred.promise;
                // shortcut can be one line
                // return $q.reject(errorResponse);
            });
        }

        function initController(){

            $controller('adminEmployeeCtrl', {
                $scope: $scope,
                empService: empService
            });
        }


        describe('Success controller initialization', function(){

            beforeEach(function(){

                successSpies();
                initController();
            });

            it('should findData by calling findEmployee',function(){
                $scope.findData();
                // calling $apply to resolve deferred promises we made in the spies
                $scope.$apply();
                expect($scope.loadingEmployee).toEqual(false);
                expect($scope.allEmployees).toEqual(employeesResponse);
            });
        });

        describe('handle controller initialization errors', function(){

            beforeEach(function(){

                rejectedSpies();
                initController();
            });

            it('should handle error when calling findEmployee', function(){
                $scope.findData();
                $scope.$apply();
                // your error expectations
            });
        });
    });
}());

在更新的问题中,你们不是在单元测试不同的方法吗?对不起@tanmay。我已经更新了spec.js测试文件。为什么要在spec中调用
scope.$apply()
?如果删除它会发生什么?因为我在假服务中使用异步调用。所以我认为它需要$apply()或$digest()。我说的对吗@tanmay?你可能需要在
$scope.findData
调用之后再做?另外,我还添加了一个处理它的答案。您的编码标准看起来很酷。但它会为一些意外的请求提供错误,这些请求是以某种方式触发的。错误:意外请求:不需要获取更多请求
/**
 * @description Tests for adminEmployeeCtrl controller
 */
(function () {

    "use strict";

    describe('Controller: adminEmployeeCtrl ', function () {

        /* jshint -W109 */
        var $q, $scope, $controller;
        var empService;
        var errorResponse = 'Not found';


        var employeesResponse = [
            {id:1,name:'mohammed' },
            {id:2,name:'ramadan' }
        ];

        beforeEach(module(
            'loadRequiredModules'
        ));

        beforeEach(inject(function (_$q_,
                                    _$controller_,
                                    _$rootScope_,
                                    _empService_) {
            $q = _$q_;
            $controller = _$controller_;
            $scope = _$rootScope_.$new();
            empService = _empService_;
        }));

        function successSpies(){

            spyOn(empService, 'findEmployee').and.callFake(function () {
                var deferred = $q.defer();
                deferred.resolve(employeesResponse);
                return deferred.promise;
                // shortcut can be one line
                // return $q.resolve(employeesResponse);
            });
        }

        function rejectedSpies(){
            spyOn(empService, 'findEmployee').and.callFake(function () {
                var deferred = $q.defer();
                deferred.reject(errorResponse);
                return deferred.promise;
                // shortcut can be one line
                // return $q.reject(errorResponse);
            });
        }

        function initController(){

            $controller('adminEmployeeCtrl', {
                $scope: $scope,
                empService: empService
            });
        }


        describe('Success controller initialization', function(){

            beforeEach(function(){

                successSpies();
                initController();
            });

            it('should findData by calling findEmployee',function(){
                $scope.findData();
                // calling $apply to resolve deferred promises we made in the spies
                $scope.$apply();
                expect($scope.loadingEmployee).toEqual(false);
                expect($scope.allEmployees).toEqual(employeesResponse);
            });
        });

        describe('handle controller initialization errors', function(){

            beforeEach(function(){

                rejectedSpies();
                initController();
            });

            it('should handle error when calling findEmployee', function(){
                $scope.findData();
                $scope.$apply();
                // your error expectations
            });
        });
    });
}());