测试John Papa的控制器调用dataservice

时间:2016-04-07 10:19:06

标签: angularjs jasmine

我正在学习使用Jasmine和Karma的BDD。

我正在关注John Papa's style guide,我在测试代码时遇到了一些困难。

我想测试这种控制器功能(来自John Papa的指南):

function getAvengers() {
    return dataservice.getAvengers()
        .then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        });
}

有了这家工厂:

function dataservice($http) {
    return {
        getAvengers: getAvengers
    };

    function getAvengers() {
        return $http.get('/api/maa')
            .then(getAvengersComplete)
            .catch(getAvengersFailed);

        function getAvengersComplete(response) {
            return response.data.results;
        }

        function getAvengersFailed(error) {
            // Fail
        }
    }
}

我做了这些测试:

describe("avengers controller", function() {

    var controller, avengers;

    beforeEach(function() {
        module('app');
    });

    beforeEach(inject(function(_$rootScope_, _$controller_, _$q_, _dataservice_) {
        dataserviceMock = _dataservice_;
        controller = _$controller_;
        vm = controller("AvengerController", { dataservice: dataserviceMock });
        $q = _$q_;
        rootScope = _$rootScope_;
        avengers = [{"id": 1}, {"id": 2}];
    }));

    it('should be created successfully', function () {
        expect(vm).toBeDefined();
    });

    it('should have called `dataservice.getAvengers`', function() {
        spyOn(dataserviceMock, 'getAvengers').and.callFake(function(){
            var deferred = $q.defer();
            return deferred.promise;
        });
        vm.getAvengers();
        expect(dataserviceMock.getAvengers).toHaveBeenCalledTimes(1);
    });

    // What I'm trying to test
    // Test 1
    it('should have Avengers', function() {
        spyOn(dataserviceMock, 'getAvengers').and.callFake(function(){
            var deferred = $q.defer();
            deferred.resolve([{"id": 1}, {"id": 2}]);
            return deferred.promise;
        );
        vm.getAvengers();
        expect(vm.avengers.length).toEqual(avengers.length);
    });
    // Test 2
    it('should have Avengers', function() {
        spyOn(dataserviceMock, 'getAvengers').and.returnValue(avengers);
        vm.getAvengers();
        expect(vm.avengers.length).toEqual(avengers.length);
    });
});

我尝试了两种不同的方法,但它没有用,我无法弄清楚如何测试avengerController.getAvengers()定义vm.avengers等于工厂调用返回的数据复仇者。

1 个答案:

答案 0 :(得分:1)

我找到了解决方案:

it("should have avengers", function() {
            deferred = $q.defer();
            spyOn(dataserviceMock, 'getAvengers').and.returnValue(deferred.promise);
            deferred.resolve(customers);
            vm.getAvengers();
            expect(dataserviceMock.getAvengers).toHaveBeenCalled();
            scope.$digest();
            expect(vm.avengers).toBeDefined();
            expect(vm.avengers).toEqual(avengers);
        });

我必须返回一个promise并使用范围。$ digest()模拟范围生命周期,如提到here