2016-07-29 68 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,那麼這將不起作用,因爲您需要它來模擬響應對象。