angularjs之Jasmine 测试返回 promise 的 ajax 请求

Demo 阅读:19 2025-06-02 22:19:02 评论:0

我是 Angular 测试的新手。

我正在尝试在服务中测试一个简单的方法,该方法通过 ajax 调用获取一些数据并使用 Jasmine 返回 promise 。

到目前为止非常不成功。

这是我正在测试的方法:

function getDefaultFibonnacci() { 
        var deferred = $q.defer(); 
 
        $http({ method: 'GET', url: '/api/fibonnacci/get' }) 
            .success(function (data) { 
                deferred.resolve(data); 
            }) 
            .error(function (data, status) { 
                deferred.reject(status); 
            }); 
 
        return deferred.promise; 
    } 

这是我的测试代码:(请注意除了“应该返回 0,1,1,2,3”之外的所有其他测试都通过了

describe('datacontext', function () { 
    var $httpBackend; 
    var $rootScope; 
    var datacontext; 
    var $q; 
 
    beforeEach(function () { 
        module('app'); 
        inject(function (_$httpBackend_, _$rootScope_, _$q_, _datacontext_) { 
            $httpBackend = _$httpBackend_; 
            $rootScope = _$rootScope_; 
            datacontext = _datacontext_; 
            $q = _$q_; 
        }); 
    }); 
 
    it('should have a getDefaultFibonnacci() function', function () { 
        expect(angular.isFunction(datacontext.getDefaultFibonnacci)).toBe(true); 
    }); 
 
    it('should return a promise', function () { 
        expect(datacontext.getDefaultFibonnacci().then).toBeDefined(); 
    }); 
 
    it('should return 0,1,1,2,3', function () { 
        var sequence = '123'; 
 
        $httpBackend.when('GET', 'app/dashboard/dashboard.html').respond(''); 
        $httpBackend.when('GET', '/api/fibonnacci/get').respond('0,1,1,2,3'); 
 
        var deferred = $q.defer(); 
        var promise = deferred.promise; 
 
        promise.then(function (response) { 
            sequence = response.success; 
        }); 
 
        datacontext.getDefaultFibonnacci().then(function (data) { deferred.resolve(data); }); 
 
        $rootScope.$digest(); 
 
        expect(sequence).toEqual('0,1,1,2,3'); 
    }); 
}); 

伙计们感谢您的所有评论。通过这次练习,我学到了很多东西。

这是我最终通过测试的代码。

function getDefaultFibonnacci() { 
        return $http({ method: 'GET', url: '/api/fibonnacci/get' }); 
    } 
 
it('should return 0,1,1,2,3', function () { 
        var sequence; 
 
        $httpBackend.whenGET('app/dashboard/dashboard.html').respond(''); 
 
        $httpBackend.expectGET('/api/fibonnacci/get').respond('0,1,1,2,3'); 
 
        datacontext.getDefaultFibonnacci().then(function (data) { 
            sequence = data.data; 
        }); 
 
        $httpBackend.flush(); 
 
        expect(sequence).toEqual('0,1,1,2,3'); 
    }); 

请您参考如下方法:

$httpBackend正是出于这个原因,有一个 flush() 方法。

flush()模拟http服务器响应,所以会触发你的$http.get()的解析。在您调用 flush() 之前,什么都不会发生(服务器尚未响应)。

因此,将您的 $rootScope.digest() 代码替换为 $httpBackend.flush() 并从那里开始工作。

此外,通过了解 $http 方法本身返回 promise ,您可以节省很多精力。

这个:

function getDefaultFibonnacci() { 
    var deferred = $q.defer(); 
 
    $http({ method: 'GET', url: '/api/fibonnacci/get' }) 
        .success(function (data) { 
            deferred.resolve(data); 
        }) 
        .error(function (data, status) { 
            deferred.reject(status); 
        }); 
 
    return deferred.promise; 
} 

可以简化为:

function getDefaultFibonnacci() { 
 
    return $http({ method: 'GET', url: '/api/fibonnacci/get' }) 
 
} 

并且会做同样的事情。

最后,您的测试中不需要其他 promise 。这已经足够了(删除所有对 $q 的引用并延迟并将其直接放在您的 $httpBackend.when(... 代码之后):

datacontext.getDefaultFibonnacci() 
.then(function (data) {  
    sequence = data; 
}); 


标签:ajax
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号