正确地使用Jasmine Spy模拟$ resource / promise服务

时间:2015-09-19 08:08:20

标签: mocking jasmine angular-promise

我无法嘲笑和测试我的角度应用。鉴于以下文件,我总是收到错误延迟未定义。

如何使用Promise正确模拟API?如何测试API确实正在运行并将响应附加到 $ scope.data 变量?

控制器

angular.module('app').controller('controllerOne', [
    '$scope',
    'API',
    function($scope, API) {
        $scope.init = function() {
            $scope.data = API.query(function(response) {
                return response;
            });
        };

    }
]);

API服务

angular.module('app').factory('API', ['$resource',
    function($resource) {
        return $resource('api/url/:Id', {
            Id: '@_id'
        }, {
            update: {
                method: 'PUT'
            }
        });
    }
]);

控制器规格

describe('app Module', function() {
    beforeEach(function() {
        module('app');
    });
    var mockAPI, q, $scope, ctrl;
    beforeEach(function() {
        mockAPI = {
            query: function() {
                var deferred = q.defer();
                return deferred.promise;
            }
        };
    });
    beforeEach(inject(function($controller, $rootScope, $q) {
        $scope = $rootScope.$new();
        q = $q;
        ctrl = $controller('controllerOne', {
            $scope: $scope,
            API: mockAPI
        });
    }));
    it('should query API', function() {
        spyOn(mockAPI, 'query').and.callThrough();
        $scope.init();
        deferred.resolve();
        $scope.$root.$digest();
        expect(mockAPI.query).toHaveBeenCalled();
    });
});

如果我运行以下代码,一切正常,但我认为这不对,因为我自己正在初始化API。

it('should query API', function() {
    mockAPI.query();
    expect(mockAPI.query).toHaveBeenCalled();
});

什么以及如何正确地做到这一点?

1 个答案:

答案 0 :(得分:0)

您遇到的问题是由于mockAPI查询中定义的延迟变量的范围。它应该在套件级别确定范围,以便可以在测试中访问它。

假设您的其余代码都很好,以下内容将解决您的问题延迟未定义

describe('app Module', function() {
    beforeEach(function() {
        module('app');
    });
    var mockAPI, deferred, q, $scope, ctrl;
    beforeEach(function() {
        mockAPI = {
            query: function() {
                deferred = q.defer();
                return deferred.promise;
            }
        };
    });
    beforeEach(inject(function($controller, $rootScope, $q) {
        $scope = $rootScope.$new();
        q = $q;
        ctrl = $controller('controllerOne', {
            $scope: $scope,
            API: mockAPI
        });
    }));
    it('should query API', function() {
        spyOn(mockAPI, 'query').and.callThrough();
        $scope.init();
        deferred.resolve();
        $scope.$root.$digest();
        expect(mockAPI.query).toHaveBeenCalled();
    });
});