$ rootScope.digest没有在Jasmine中完成一个承诺

时间:2015-09-22 13:14:53

标签: javascript angularjs jasmine angular-promise

我们目前正在尝试测试我们的角度服务,这些服务使用promises将值返回给控制器。问题是我们附加到.then的函数不会在Jasmine中被调用。

我们发现在返回promise之后向函数添加$ rootScope.digest()允许调用同步promises但是它仍然不适用于异步promise。

到目前为止的代码是

    beforeEach(inject(function (Service, $rootScope)
    {
        service = Service;
        root = $rootScope;
    }));

    it('gets all the available products', function (done)
    {
        service.getData().then(function (data)
        {
            expect(data).not.toBeNull();
            expect(data.length).toBeGreaterThan(0);
            done();
        });
        root.$digest();
    });

在这种情况下,promise被称为罚款,但如果它是异步的,则不会被调用,因为承诺尚未准备好"消化"当根。$ digest()被调用时。

是否有某种方法可以告诉我何时获得解决方案,以便我可以调用摘要?或者也许会自动做到这一点?谢谢;)

我们必须测试部分服务(删除错误处理):

var app = angular.module('service', []);

/**
 * Service for accessing data relating to the updates/downloads
 * */
app.factory('Service', function ($q)
{
     ... init

    function getData()
    {
        var deffered = $q.defer();

        var processors = [displayNameProc];

        downloads.getData(function (err, data)
        {
            chain.process(processors, data, function (err, processedData)
            {
                deffered.resolve(processedData);
            });
        });

        return deffered.promise;
    }
    ...

在出现问题的情况下,当service.getData为异步时,promise将被解析,但不会调用从测试代码附加到该promise的函数,因为已经调用了根。$ digest。希望这能提供更多信息

解决方法

var interval;
beforeEach(inject(function ($rootScope)
{
    if(!interval)
    {
        interval = function ()
        {
            $rootScope.$digest();
        };
        window.setInterval(interval, /*timing*/);
    }
}));

我最终使用上面的解决方法反复调用摘要,因此每一层承诺都有机会运行......它不理想或漂亮但它适用于测试......

1 个答案:

答案 0 :(得分:1)

你应该把你的断言移到当时我认为:

You need to sign in or sign up before continuing.

<强>更新

plunkr与以下评论分开,以显示如何测试异步通话。

为服务添加了$ timeout:

beforeEach(inject(function (Service, $rootScope)
{
    service = Service;
    root = $rootScope;
}));

it('gets all the available products', function (done)
{
    var result;
    service.getData().then(function (data)
    {
        result = data;
        done();
    });

    root.$digest();

    expect(result ).not.toBeNull();
    expect(result .length).toBeGreaterThan(0);
});

在断言之前我正在冲洗$ timeout:

var app = angular.module('bad-service', []);

app.service('BadService', function ($q, $interval, $timeout)
{
    this.innerPromise = function(){
      var task = $q.defer();
      console.log('Inside inner promise');

      $timeout(function() {
        console.log('Inner promise timer fired');
        task.resolve();
      }, 500);
      // $interval(function(){

      // }, 500, 1);
      return task.promise;
    }
});