簡體   English   中英

函數中Restangular的jasmine測試用例

[英]jasmine test case for Restangular within a function

如何為Rectangular編寫茉莉花測試,如下所示

腳本

$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();

        }));
    });
});

你有多個問題:

首先,要回答你的問題,請使用toHavebeenCalled,你必須先創建一個間諜。

我要做的是將setMyEmployees放在作用域級別,然后在作用域上添加一個間諜

spyOn($scope);

但是您有一個測試會產生異步請求,因此您的測試用例將失敗,因為它將在異步請求成功之前到達終點。

使用jasmine 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);
});

我更喜歡promise語法:

$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
        });
    }));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM