Angularjs 测试John Papa';s控制器对数据服务的调用

Angularjs 测试John Papa';s控制器对数据服务的调用,angularjs,jasmine,Angularjs,Jasmine,我正在与茉莉花和因果报应学习BDD 我正在跟进,测试代码时遇到了一些困难 我想测试这种控制器功能(来自John Papa的指南): 对于该工厂: function dataservice($http) { return { getAvengers: getAvengers }; function getAvengers() { return $http.get('/api/maa') .then(getAvenge

我正在与茉莉花和因果报应学习BDD

我正在跟进,测试代码时遇到了一些困难

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

对于该工厂:

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定义为等于工厂调用返回的数据avengers。

我找到了一个解决方案:

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);
        });

我必须返回一个承诺并使用scope.$digest()来模拟前面提到的scope生命周期。

您能详细说明什么不起作用吗?是否由于承诺,测试
应该有复仇者
?测试1返回“预期0等于2”,测试2返回“未定义不是构造函数(评估'dataservice.getAvengers()。然后(getAvengersComplete)'”。
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);
        });