AngularJS,Jasmine:测试使用$ http调用服务的控制器函数

时间:2014-05-28 10:00:03

标签: javascript angularjs unit-testing testing jasmine

我正在尝试测试使用controller的{​​{1}}。但是,service目前为service,因为我想隔离null中的测试。

以下是当前测试,由于controllerBoardService

,因此无效
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()

最后是Aaaand,$scope.addTask = function(category, task) { BoardService.addTask({name : task, category : category.id}).success(function(task_id) { // Removed code for simplicity }); } 中的函数:

service

2 个答案:

答案 0 :(得分:0)

我认为这个想法是模仿一个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);
});

答案 1 :(得分:0)

首先,您需要模拟BoardService并存根您需要测试的功能。

beforeEach(inject(function ($rootScope, $controller, $q) {
    fakeDashboardItemService = {
        addTask: function () {}
    };

    scope = $rootScope.$new();
    q = $q;
    BoardController = $controller('BoardController', {
        $scope: scope, 
        BoardService: fakeBoardService
    });
}));

然后你可以spyOn你的存根功能,设置你的测试用例,并返回承诺。我在这里使用$ digest来提高速度并避免弄乱根范围($apply vs $digest in directive testing

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承诺,而不仅仅是从测试函数返回承诺时不会调用的成功和错误子函数。请注意,.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
    });
}