函数内 Restangular 的茉莉花测试用例

jasmine test case for Restangular within a function

本文关键字:茉莉花 测试用例 Restangular 函数      更新时间:2023-09-26

如何为如下所示的场景编写矩形的茉莉花测试

脚本

$scope.allEmployees = [{
            visible: true,
            empId: "EMP148"
 }];
$scope.employeeDocuments = {  "EMP148": [{
                                        "empId": "EMP148",
                                        "department": "Sales",
                                        "firstName": "Manu",
                                        "lastName": "Mathew",
                                        "place": "Kolkata"
                                        }]
                           };
var employeesCopy = angular.copy($scope.allEmployees);
$scope.allEmployees.push({visible: true, empId: "EMP489"});  
$scope.addEmployees = function (employeesCopy) {
    var newEmployee = {visible: true, empId: "EMP489"};
    var emplyeeList = {
        employees: $scope.allEmployees,
        newEmployee: newEmployee
    };
    Restangular.all('emp/getEmployees').post(emplyeeList).then(function (employees) {
        if (!_.isEmpty(employees[emplyeeList.newEmployee.empId])) {
            if ($scope.employeeDocuments.hasOwnProperty(emplyeeList.newEmployee.empId)) {
                delete $scope.employeeDocuments[emplyeeList.newEmployee.empId];
            }
            $scope.employeeDocuments[emplyeeList.newEmployee.empId] = employees[emplyeeList.newEmployee.empId];
            setMyEmployees(true);
            $scope.flag = true;
            console.log("success");
        } else {
            $scope.employeeDocuments = employeesCopy;
            console.log("no documents");
        }
        $scope.flag = false;
    }, function (error) {
        console.log("failed");
        $scope.flag = false;
    });
};
$scope.addEmployees(employeesCopy);
setMyEmployees = function (flag)
{
    // other implementation
};

我已经编写了一个如下所示的测试用例,但是我得到了像spyOn could not find an object to spy upon for all()这样的异常

测试用例

工作演示 - 包含完整的逻辑以及测试用例

describe('Testing Controllers', function() {
    describe('Testing EmployeeController Controller', function() {
        var EmployeeController, $scope, $httpBackend, Restangular;
        beforeEach(function() {
           module('emp');
        }); 
        beforeEach(inject(function($controller, $rootScope, $filter, $injector, Restangular, $httpBackend) {
            $scope = $rootScope.$new();
            $httpBackend = $httpBackend;
            Restangular = $injector.get("Restangular");
            EmployeeController = $controller('EmployeeController ', {
                $rootScope: $rootScope,
                $scope: $scope,
                $filter: $filter
            });
        }));
        it('should add new employees when addEmployees() is called', inject(function($httpBackend)
        {
           $scope.allEmployees = [{
                                    visible: true,
                                    empId: "EMP148"
                              }];
           $scope.employeeDocuments = {  "EMP148": [{
                                            "empId": "EMP148",
                                            "department": "Sales",
                                            "firstName": "Manu",
                                            "lastName": "Mathew",
                                            "place": "Kolkata"
                                            }]
                                   };
           var employeesCopy = angular.copy($scope.allEmployees);
           spyOn(Restangular, 'all').andCallThrough();
           var newEmployee = {visible: true, empId: "EMP489"};
           var emplyeeList = {
                employees: $scope.allEmployees,
                newEmployee: newEmployee
           };
           var mockToReturn = {
                "EMP489": [{
                "empId": "EMP489",
                "department": "Sales",
                "firstName": "Ram",
                "lastName": "Mohan",
                "place": "Delhi"
                }]
            };
            $scope.addEmployees(employeesCopy);
            $httpBackend.expectPOST('emp/getEmployees',emplyeeList).respond(mockToReturn);
            expect(Restangular.all).toHaveBeenCalledWith('emp/getEmployees');
            expect(setMyEmployees(true)).toHaveBeenCalled();
        }));
    });
});

你有多重问题:

首先

,要回答你的问题,你必须首先创建一个间谍。

我要做的是将 setMyEmployees 放在范围级别,然后在范围上添加间谍

spyOn($scope);

但是您有一个发出异步请求的测试,因此您的测试用例将失败,因为它将在异步请求成功之前到达终点。

使用茉莉花 2,您可以使用 done() 进行异步测试:

it('should add new employees when addEmployees() is called', function(done) 
{
    //call when asyncronous operation is finish
    done();
}

但是,以您创建函数的方式,您无法使用 done。你必须在你的方法或承诺中有一个回调块

回调:

$scope.addEmployees = function(employeesCopy, success, failure)
{
    //code
    Restangular.all('user/getEmployees').post(emplyeeList).then(function(employees)
    {
        if (!_.isEmpty(employees[emplyeeList.employeeId]))
        {
           // code
        }
        else
        {
            // code
        }
        success();
        $scope.flag = false;
    }, function(error)
    {
        failure();
        $scope.flag = false;
    });
};

注意 toHaveBeenCall 语法

it('should add new employees when addEmployees() is called', function(done) 
{
var employeesCopy = {
    firstName: "Manu",
    lastName: "Sam"
};
spyOn($scope);
$scope.addEmployees(employeesCopy, function(){
    done();
});
expect($scope.setMyEmployees).toHaveBeenCalledWith(true);
});

我更喜欢承诺语法:

$scope.addEmployees = function(employeesCopy, defer)
{
    //code
    Restangular.all('user/getEmployees').post(emplyeeList).then(function(employees)
    {
        if (!_.isEmpty(employees[emplyeeList.employeeId]))
        {
           // code
        }
        else
        {
            // code
        }
        defer.resolve();
        $scope.flag = false;
    }, function(error)
    {
        defer.reject();
        $scope.flag = false;
    });
};

it('should add new employees when addEmployees() is called', function(done) 
{
var employeesCopy = {
    firstName: "Manu",
    lastName: "Sam"
};
spyOn($scope);
var defer = $q.defer;
defer.promise.then(function(){
    console.log("success");
    done();
}, function (){
    done();
    console.log("error");
});
$scope.addEmployees(employeesCopy, defer);
expect($scope.setMyEmployees).toHaveBeenCalledWith(true);
});

如果你希望你的测试是真正的单一的,你将遇到的最后一个问题是模拟网络调用(否则你也在测试后端答案,这可能是你想要的)如果你想模拟电话,你应该看看$httpBackend,这篇博文似乎有更多信息:https://ath3nd.wordpress.com/2013/08/05/15/(不是我的)

编辑,添加依赖关系进行测试,在it()之前,使用beforeEach :

var myService, Restangular;
    beforeEach(function() {
        inject(function($injector) {
            myService = $injector.get('MyService');//exemple service
            Restangular = $injector.get("Restangular");
        });
    });

编辑 2 :

好的,我没有正确解释它,请尝试:

beforeEach(inject(function($controller, $rootScope, $filter, $injector, _Restangular_, _$httpBackend_) {
        $scope = $rootScope.$new();
        $httpBackend = _$httpBackend_;
        Restangular = _Restangular_;
        EmployeeController = $controller('EmployeeController ', {
            $rootScope: $rootScope,
            $scope: $scope,
            $filter: $filter
        });
    }));