2015-12-28 13 views
9

Ich habe eine Methode in einem Dienst, der Unterstrich Entprellen verwendet.Testen einer entprellten Funktion in Angular mit Jasmin ruft nie die Funktion

Innerhalb dieser Methode ist ein Aufruf einer Methode auf einem anderen Dienst. Ich versuche zu testen, dass der andere Dienst aufgerufen wird.

In meiner Versuche, die entprellten Methode zu testen, die Methode der verschiedenen Dienste wird nie und Jasmin irgendwie genannt: ‚Expected Spion aMethod genannt worden zu sein‘

Ich weiß für eine Tatsache, dass es aufgerufen wird (es meldet sich an die Konsole in Chrom), es heißt nur, nachdem die Erwartung bereits fehlgeschlagen ist.

So ... (vorzugsweise) ohne Zugabe von Sinon oder einem anderen Abhängigkeit und mit
Bonuspunkten * zu einer Lösung gegeben muss nicht die _.debounce in einen $ timeout drehen ...

Wie machen?

angular.module('derp', []) 
.service('herp', function(){ 
    return { 
    aMethod: function(){ 
     console.log('called!'); 
     return 'blown'; 
    } 
    }; 
}) 
.service('Whoa', ['herp', function(herp){ 
    function Whoa(){ 
    var that = this; 
    this.mindStatus = 'meh'; 
    this.getMind = _.debounce(function(){ 
     that.mindStatus = herp.aMethod(); 
    }, 300); 
    } 
    return Whoa; 
}]); 

Tests:

describe('Whoa', function(){ 
    var $injector, whoa, herp; 

    beforeEach(function(){ 
    module('derp'); 
    inject(function(_$injector_){ 
     var Whoa; 
     $injector = _$injector_; 
     Whoa = $injector.get('Whoa'); 
     herp = $injector.get('herp'); 
     whoa = new Whoa(); 
    }); 
    }); 

    beforeEach(function(){ 
    spyOn(herp, 'aMethod').andCallThrough(); 
    }); 

    it('has a method getMind, that calls herp.aMethod', function(){ 
    whoa.getMind(); 
    expect(herp.aMethod).toHaveBeenCalled(); 
    }); 
}); 

Warum die Winkel Testing Götter haben mich verlassen?

* Ich weiß nicht, wie man auf stackoverflow tatsächlich Bonuspunkte gibt, aber wenn es möglich ist, werde ich es tun.

Antwort

13

Sie müssen nur lodash debounce Methode verspotten:

describe('Whoa', function(){ 
    var $injector, whoa, herp; 

    beforeEach(function(){ 
    module('derp'); 
    spyOn(_, 'debounce').and.callFake(function(cb) { return function() { cb(); } }); 
    inject(function(_$injector_){ 
     var Whoa; 
     $injector = _$injector_; 
     Whoa = $injector.get('Whoa'); 
     herp = $injector.get('herp'); 
     whoa = new Whoa(); 
    }); 
    }); 

    beforeEach(function(){ 
    spyOn(herp, 'aMethod').andCallThrough(); 
    }); 

    it('has a method getMind, that calls herp.aMethod', function(){ 
    whoa.getMind(); 
    expect(herp.aMethod).toHaveBeenCalled(); 
    }); 
}); 
+0

Nein. Funktioniert immer noch nicht. In beiden Fällen wird herp.aMethod genannt, aber beide werden nicht vor der Erwartung aufgerufen. –

+0

Ich wünschte ich hätte Chai wie versprochen. ein "irgendwann" würde das beheben. –

+0

Setzen Sie einen Breakpoint innerhalb der anonymen Funktion innerhalb des Callfake und überprüfen Sie den Stack, um zu sehen, woher er aufgerufen wird. – Wawy

1

Angular $timeout hat den Vorteil in Tests, weil es in Tests verspottet wird synchron sein. Der eine wird diesen Vorteil nicht haben, wenn asynchrone Werkzeuge von Drittanbietern verwendet werden. Im allgemeinen asynchronen Spezifikationen wird so aussehen:

var maxDelay = 500; 

    ... 
    it('has a method getMind, that calls herp.aMethod', function (done){ 
    whoa.getMind(); 
    setTimeout(function() { 
     expect(herp.aMethod).toHaveBeenCalled(); 
     done(); 
    }, maxDelay); 
    }); 

Da Unders debounce nicht flush Funktionalität anbietet (während die aktuelle Version von Lodash debouncedoes), asynchrone Prüfung ist die beste Option zur Verfügung.

+0

das funktioniert für mich, mit einer Zeitüberschreitung von 0 – dliu120