2016-07-29 15 views
2
gelten

Ich habe diesen Service.

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

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

Ich teste es mit Karma/Mocca/chai:

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(); 
    });  
}); 

Da $ q Versprechen funktioniert nicht gut mit Mocha ich bin this answer, die $timeout.flush() hinzufügen, um die .then Methode des Versprechens zu erzwingen, ausgeführt werden.

Das Problem ist, nach dem Aufruf .flush(), alle meine app aufwacht und ich anfangen, diese Fehler von Winkel Mocks zu bekommen:

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

Ich weiß über $ httpBackend, aber es wäre geisteskrank, um alle Anforderungen zu verspotten, die meine App beim Start macht.

Gibt es einen Weg zu $q Versprechungen Arbeit mit Mokka ohne Aufruf $timeout.flush() oder ?

+0

Das Thema der Frage ist Chai, nicht Mocha. Mögliches Duplikat von http://StackOverflow.com/a/37374041/3731501 – estus

+0

Das Thema der Frage ist der $ Q-Service und wie ich $ Q verspricht, ohne Anwendung/flush gelöst werden. Chai als nichts damit zu tun, da ich nicht Chai-wie versprochen. Zumindest sehe ich so die Situation, wenn Sie nicht einverstanden sind, versuchen Sie es besser zu erklären. – pietrovismara

+0

Es ist Chai, die Behauptungen macht, nicht Mocha. Nun, Sie können in Betracht ziehen, Chai-as-Versprochen zu verwenden, es ist die Art und Weise, wie $ q Zusicherungszusicherungen durchgeführt werden können, ohne '$ apply()' oder '$ digest()' nach 'then' aufzurufen. – estus

Antwort

1

Wie gezeigt here, chai-as-promised kann verwendet werden, um zu bestätigen $q verspricht. Mit diesem Setup

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

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

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

Zyklen verdauen wird automatisch auf Versprechen Behauptungen ausgelöst werden, die ganze Versprechen Kette ausführt.

In diesem Fall wird die spec

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

$digest() Aufruf weglassen können und werden

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

Beachten Sie, dass $q Versprechen synchron sind, sollten sie nicht von Mocha spec oder done Rückruf aufrufen zurückgegeben werden.

+0

Ich habe versucht, Ihre Lösung, aber das Ergebnis ist das gleiche. Wenn ich '$ rootScope. $ Digest()', sei es in 'chaiAsPromised.transferPromiseness' oder wo auch immer, rufe ich die gleichen Fehler bei unerwarteten Anfragen auf. In der Tat, was ich von Anfang an gefragt habe, ist, wie man diesen Test ohne Verwendung von $ digest/$ apply/$ flush durchführt. An dieser Stelle denke ich, dass es keine Lösung gibt. – pietrovismara

+1

Es scheint, dass Sie die Dinge vermischen. Dies alles sind getrennte Anliegen. '$ digest()' ist kein Allheilmittel. Sie müssen '$ digest()' auslösen, um $ q Versprechungen auszuführen (dies ist, was die Antwort abdeckt). Sie müssen 'flush()' aufrufen, um Timeout-Timeouts von $ auszuführen. Sie müssen $ httpBackend-Anfragen in Unit-Tests nachahmen. Es gibt keine Notwendigkeit, sie alle zu verspotten - nur die Anforderungen, die von der getesteten Einheit gestellt werden. So funktioniert der Angular-Test. – estus

0

Hier ist eine alternative Strategie, die wir verwenden, weil wir nie tatsächlich $httpBackend brauchen, aber es manchmal (zufällig) ausfällt Anfragen nach Vorlagen machen von Richtlinien verwendet werden (auch wenn diese Vorlagen in $templateCache verfügbar sind):

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

Natürlich, wenn Sie tatsächlich $httpBackend in anderen Fällen verwenden, dann wird dies nicht funktionieren, da Sie es benötigen, um Antwortobjekte zu verspotten.

Verwandte Themen