Jasmine测试返回promise的ajax请求

时间:2014-09-07 09:14:57

标签: angularjs jasmine promise

我是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');
    });

3 个答案:

答案 0 :(得分:4)

出于这个原因,

$httpBackend有一个 flush() 方法。

flush()模拟http服务器响应,因此它将触发$http.get()的解析。在您致电flush()之前,不会发生任何事情(服务器尚未响应)。

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

此外,您可以通过了解$http方法本身返回承诺来节省大量精力。

此:

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

}

并会做同样的事情。

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

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

答案 1 :(得分:1)

你是否期望一个对象{success:“0,1,1,2,3”}作为来自http服务的响应?当承诺解决时,您正在使用response.success

promise.then(function (response) {
            sequence = response.success;
        });

而你正在返回一个字符串'0,1,1,2,3'

$httpBackend.when('GET', '/api/fibonnacci/get').respond('0,1,1,2,3');

此外,从代码中我看到您不需要创建另一个承诺来测试您的方法。

试试这个:

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

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

        $rootScope.$digest();

        expect(sequence).toEqual('0,1,1,2,3');
    });

答案 2 :(得分:1)

您最不重要的想法是在使用数据之前在请求之后的某个时刻致电$httpBackend.flush()

此外,您不需要创建额外的承诺。

it('should return 0,1,1,2,3', function () {
    var sequence;

    // Use the shorthand method whenGET
    $httpBackend.whenGET('app/dashboard/dashboard.html').respond('');

    // We should probably test that this request is actually made, so use expect<method>
    $httpBackend.expectGET('/api/fibonnacci/get').respond('0,1,1,2,3');

    // Leave out the extra promise code.
    // var deferred = $q.defer();
    // var promise = deferred.promise;

    // promise.then(function (response) {
    //     sequence = response.success;
    // });

    // datacontext.getDefaultFibonnacci().then(function (data) { deferred.resolve(data); });

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

    $httpBackend.flush(); // Flush the backend. Important!
    // $rootScope.$digest(); // I don't think this is necessary.

    expect(sequence).toEqual('0,1,1,2,3');
});

如果您设置应用

,则不会调用html模板