mercredi 18 novembre 2015

How can I avoid "$digest already in progress" error in my AngularJS test?

I'm having a problem with running one of my AngularJS tests in Karma using Chrome. The test works in PhantomJS.

When running the test using Chrome I get the following error:

Chrome 46.0.2490 (Windows 7 0.0.0) ERROR
  Uncaught Error: [$rootScope:inprog] $digest already in progress
  http://ift.tt/1WYxj6G
  at C:/dev/unionvms_eu/branches/dev/unionvms-web/bower_components/angular-mocks/angular-mocks.js:275

Test:

describe('todoRestService', function() {

    beforeEach(module('todoApp'));

    //MOCK RESOURCE
    beforeEach(function () {
        var mockResource = {
            todo: function() {
                return {
                    update: function(todoDTO, callback) {
                        callback({
                            code : 200,
                            data: {
                                status : 'CLOSED'
                            }
                        });
                    },
                }
            },
        };

        module(function ($provide) {
            $provide.value('todoRestFactory', mockResource);
        });

    });

    it("updateTodoStatus should send request to backend and return received object", inject(function($rootScope, $log, todoRestService, Todo) {
        var todo = new Todo();
        todo.status = "CLOSED";

        var resolved = false;
        $rootScope.$apply(function(){
            todoRestService.updateTodoStatus(todo).then(function(updatedTodo){
                resolved = true;
                expect(updatedTodo.status).toEqual(todo.status);
            });
        });
        $rootScope.$digest();
        expect(resolved).toBe(true);
    }));

});

The code:

angular.module('todoApp')
    .factory('todoRestFactory',function($resource) {
        return {
            todo : function(){
                return $resource('/app/todo', {}, {
                    update: {method: 'PUT'}
                });
            },
        };
    })
.factory('todoRestService', function($q, $log, todoRestFactory, Todo){

    var updateTodoStatus = function(todo){
        var deferred = $q.defer();
        todoRestFactory.todo().update(todo.DTO(), function(response) {
            if(response.code !== 200){
                deferred.reject("Invalid response status");
                return;
            }
            deferred.resolve(Todo.fromDTO(response.data));
        }, function(error) {
            $log.error("Error updating todo status");
            $log.error(error);
            deferred.reject(error);
        });
        return deferred.promise;
    };

    return {
        updateTodoStatus: updateTodoStatus,
    };
});

If I remove $rootScope.$digest(); from the test, the error goes away but the last assertion will fail. How can I make the test work?

Aucun commentaire:

Enregistrer un commentaire