[英]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.