2016-07-29 120 views
2

我有这样的服务:

angular.module('domeeApp') 
     .factory('streamWidget', streamWidgetFactory); 

    function streamWidgetFactory($q) { 
     return { 
      loadContent: function() { 
       return $q(function(resolve, reject) { 
        resolve('test'); 
       }) 
      } 
     } 
    } 

我果报/摩卡/柴测试它:

describe('streamWidget', function() { 
    beforeEach(module('domeeApp')); 
    var streamWidget; 
    var $timeout; 

    beforeEach(inject(function(_$timeout_, _streamWidget_) { 
     streamWidget = _streamWidget_; 
     $timeout = _$timeout_; 
    })); 


    it('should load new content', function(done) {   
     streamWidget.loadContent() 
     .then(function(res) { 
      expect(res).to.equal('test'); 
      done(); 
     }) 
     .catch(function(){}) 
     $timeout.flush(); 
    });  
}); 

由于$ Q承诺不符合摩卡我很喜欢this answer,这表示要添加$timeout.flush()来强制.then承诺的方法被执行。

的问题是,调用.flush()之后,我的所有应用被唤醒,我开始从角嘲笑得到这个错误:

Error: Unexpected request: GET /partials/page/view/index

我知道约$ httpBackend,但它会是疯狂嘲笑我的应用程序启动时的所有请求。

有没有办法使$q承诺与摩卡一起工作,而无需致电$timeout.flush()$rootScope.$apply()

+0

问题的主题是柴,而不是摩卡。可能的重复http://stackoverflow.com/a/37374041/3731501 – estus

+0

问题的主题是$ q服务,以及我如何强制$ q promise在不使用apply/flush的情况下解决。柴没有任何关系,因为我没有使用chai-as-promise。至少,这是我看到的情况,如果你不同意,试着更好地解释它。 – pietrovismara

+0

这是柴,断言,而不是摩卡。那么,你可以考虑使用chai-as-promised,那么$'promise可以在'then'后面调用'apply()'或'$ digest()'来完成断言。 – estus

回答

1

herechai-as-promised可用于声明$q承诺。 采用这种设置

chaiAsPromised.transferPromiseness = function (assertion, promise) { 
    assertion.then = promise.then.bind(promise); 

    if (!('$$state' in promise)) 
    return; 

    inject(function ($rootScope) { 
    if (!$rootScope.$$phase) 
     $rootScope.$digest(); 
    }); 
}; 

消化周期将自动上承诺断言来触发,执行整个承诺链。

在这种情况下,规范

it('...',() => { 
    ... 
    expect(...).to.eventually...; 
    expect(...).to.eventually...; 
    $rootScope.$digest(); 
}); 

可以省略$digest()呼叫并成为

it('...',() => { 
    ... 
    expect(...).to.eventually...; 
    expect(...).to.eventually...; 
}); 

注意$q承诺是同步的,他们不应该从摩卡规范返回或致电done回调。

+0

我试过你的解决方案,但结果是一样的。当我调用'$ rootScope。$ digest()',在'chaiAsPromised.transferPromiseness'或其他任何地方,我开始得到关于意外请求的相同错误。事实上,我从一开始就问的是如何在不使用$ digest/$ apply/$ flush的情况下进行此测试。在这一点上,我想没有解决方案。 – pietrovismara

+1

看来你把事情搞混了。这些都是单独的担忧。 '$ digest()'不是万能的。你需要触发'$ digest()'来执行$ q promise(这就是答案所涵盖的内容)。你需要调用'flush()'来执行$ timeout超时。您需要在单元测试中模拟$ httpBackend请求。没有必要嘲笑他们全部 - 只有被测单位提出的要求。这是角度测试的工作原理。 – estus

0

下面是我们使用,因为我们从未实际需要$httpBackend另一种策略,但有时(随机)失败时,借指令(即使这些模板$templateCache可用)使用的模板要求:

beforeEach(function() { 
    module('app', function($provide) { 
    // This is using jasmine, but the idea is the same with mocha. 
    // Basically just replace $httpBackend with a function that does nothing. 
    $provide.constant('$httpBackend', jasmine.createSpy('$httpBackend')); 
    }); 
}); 

当然,如果您在其他情况下实际上使用使用$httpBackend,那么这将不起作用,因为您需要它来模拟响应对象。