用http调用服务的Karma测试控制器

时间:2016-08-25 06:58:45

标签: angularjs unit-testing karma-jasmine

有人可以告诉我在我的控制器函数getData和工厂函数上运行测试的最佳方法。我很困惑,不知道从哪里开始。你会如何为下面的代码编写测试?

myApp.controller('myController', ['$scope', 'myFactory', function ($scope, myFactory) {

    $scope.getData = function(id) {
        var promise = myFactory.GetData('/dta/GetData?Id=' + id);
        promise
        .then(function (success) {
            $scope.result = success;
        }, function (error) {
            $scope.error = true;
        });
    }
});


myApp.factory('myFactory', ['$http', function ($http) {
    return {
        GetData: function (url) {
            return $http.get(url)
            .then(function (response) {
                return response.data;
             }, function (error) {
                return error;
             });
        }
    }
}]);

1 个答案:

答案 0 :(得分:1)

您需要单独测试每个组件(这是单元测试的用途)。对于控制器来说就是这样的东西

describe('myController test', () => {
    let scope, myFactory;

    beforeEach(() => {
        myFactory = jasmine.createSpyObj('myFactory', ['GetData']);            

        module('your-module-name');
        inject(function($rootScope, $controller) {
            scope = $rootScope.$new();

            $controller('myController', {
                $scope: scope,
                myFactory: myfactory
            });
        });
    });

    it('getData assigns result on success', inject(function($q) {
        let id = 1, success = 'success';
        myFactory.GetData.and.returnValue($q.when(success));

        scope.getData(id);
        expect(myFactory.GetData).toHaveBeenCalledWith('/dta/GetData?Id=' + id);
        scope.$digest(); // resolve promises
        expect(scope.result).toBe(success);
    }));

    it('getData assigns error on rejections', inject(function($q) {
        myFactory.GetData.and.returnValue($q.reject('error'));

        scope.getData('whatever');
        scope.$digest();
        expect(scope.error).toEqual(true);
    }));
});

对于您的工厂,您将创建单独的describe并注入并配置$httpBackend。文档中有很多例子。

仅供参考,您应该省略工厂中的错误处理程序,即

return $http.get(url).then(response => response.data);

或者如果您不喜欢ES2015

return $http.get(url).then(function(response) {
    return response.data;
});

因为您正在将失败的请求转换为成功的承诺。

事实上,我会更进一步让你的GetData工厂比仅仅$http包装器更有用

GetData: function(id) {
    return $http.get('/dta/GetData', {
        params: { Id: id }
    }).then(function(res) {
        return res.data;
    });
}