[英]AngularJS, Jasmine: Testing a controller function calling a service using $http
我正在嘗試測試使用service
的controller
。 但是,該service
當前為null
因為我想隔離controller
的測試。
這是當前的測試,由於BoardService
為null
,因此無法正常工作
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
BoardController = $controller('BoardController', {
$scope: scope,
board: {id: 1, tasks: {}},
BoardService: null
});
}));
it ("should add a new task", function() {
var tasksBefore = scope.board.tasks.length;
scope.addTask(category, 'this is a new task');
var tasksAfter = scope.board.tasks.length;
expect(tasksAfter).toBe(tasksBefore + 1);
});
這是來自控制器的addTask()
函數:
$scope.addTask = function(category, task) {
BoardService.addTask({name : task, category : category.id}).success(function(task_id) {
// Removed code for simplicity
});
}
最后, service
的功能:
this.addTask = function(data) {
return $http.post($rootScope.serverRoot + '/task/create', data);
}
我認為這個想法是為了模擬BroadService
...所以也許像...
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
var boardService = {
addTask:function(task){
var d = $q.defer();
d.resolve(/*Whatever your service function returns: if its just a task_id, return an int or something*/);
return d.promise;
};
};
BoardController = $controller('BoardController', {
$scope: scope,
board: {id: 1, tasks: {}},
BoardService: boardService
});
}));
it ("should add a new task", function() {
var tasksBefore = scope.board.tasks.length;
scope.addTask(category, 'this is a new task');
scope.$apply();
var tasksAfter = scope.board.tasks.length;
expect(tasksAfter).toBe(tasksBefore + 1);
});
首先,您需要模擬BoardService並對需要測試的功能進行存根。
beforeEach(inject(function ($rootScope, $controller, $q) {
fakeDashboardItemService = {
addTask: function () {}
};
scope = $rootScope.$new();
q = $q;
BoardController = $controller('BoardController', {
$scope: scope,
BoardService: fakeBoardService
});
}));
然后,您可以spyOn
已存根的那個函數,設置測試用例並返回promise。 我在這里使用$ digest來提高速度,並避免弄亂根范圍( 指令測試中的$ apply與$ digest )
it ("should add a new task", function() {
spyOn(fakeBoardService, 'addTask').andCallFake(function () {
var deferred = q.defer();
deferred.resolve(/*return test case here*/);
return deferred.promise;
})
var tasksBefore = scope.board.tasks.length;
scope.addTask(category, 'this is a new task');
scope.$digest();
var tasksAfter = scope.board.tasks.length;
expect(tasksAfter).toBe(tasksBefore + 1);
});
最后一個重要的變化是,你應該重新因子用你的控制器的方法.then
,而不是.success.
和.error
。 這樣,您就可以處理完整的$http
Promise,而不僅僅是處理從測試函數返回Promise時不會調用的成功和錯誤子功能。 請注意, .then
接收整個響應,而不僅僅是數據。
$scope.addTask = function(category, task) {
BoardService.addTask({name: task, category: category.id}).then(function(response) {
// handle success case
var task_id = response.data;
}, function(err) {
// handle error case
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.