2016-05-24 17 views
3

Ich habe eine einfache Fabrik

angular.module('myApp.dice',[]).factory('Dice', ['$interval', function($interval){ 
    return { 
     rollDice: function(){ 
     return $interval(function(c){ 
       count++; 
      }, 100, 18, false, 0); 
     } 
    }; 
}]); 

In meinem Testfall I

describe('rolling dice', function(){ 
     var promise, promiseCalled = false, notify = false; 
     beforeEach(inject(function(){ 
     promise = Dice.rollDice(); 
     promise.then(function(){ 
      promiseCalled = true; 
     }); 

     })); 

     it('should invoke a promise', inject(function(){ 
     expect(promise).toBeDefined(); 
     })); 

     it('should set promiseCalled', inject(function($rootScope, $interval){ 


     expect(promiseCalled).toEqual(true); 
     })); 
    }); 

habe Wie kann ich das Intervall auslösen oder das Versprechen lösen? um den Test wahr zu machen?

Antwort

7

Siehe plunker

Sie benötigen '$interval.flush' von AngularJS-Mocks verwenden und dann für das Ergebnis zu testen. Ich habe mir die Freiheit genommen, dem Würfelobjekt count zuzuordnen, da es in Ihrem Codebeispiel nicht definiert ist.

Gibt es einen Grund, warum $interval mit invokeApply = false aufgerufen wird? denn dann müssen Sie manuell $apply aufrufen.

describe('rolling dice', function(){ 
    var $interval, $rootScope, dice; 

    beforeEach(module('plunker')); 

    beforeEach(inject(function(_$interval_, _$rootScope_, _Dice_){ 
     $interval = _$interval_; 
     $rootScope = _$rootScope_; 
     dice = _Dice_; 
    })); 

    it('should increment count', inject(function(){ 
     dice.rollDice(); 
     // Move forward by 100 milliseconds 
     $interval.flush(100); 
     // Need to call apply because $interval was called with invokeApply = false 
     $rootScope.$apply(); 
     expect(dice.count).toBe(1); 
    })); 
    }); 

mit Hersteller:

würde Der Testfall sein

app.factory('Dice', ['$interval', function($interval){ 
    var self= { 
     count: 0, 
     rollDice: function(){ 
     return $interval(function() { 
       self.count++; 
      }, 100, 18, false, 0); 
     } 
    }; 
    return self; 
}]); 

EDIT: Ich ziehe das Ergebnis eines Funktionsaufrufs zu testen, aber vielleicht haben Sie einen Anwendungsfall für die Prüfung, dass ein Versprechen-Funktion wird aufgerufen, so könnte dies sein, was Sie suchen. Aus der eckigen Dokumentation unter $interval heißt es, dass es

zurückgibt. Ein Versprechen, das bei jeder Iteration benachrichtigt wird.

Stichwort sein gemeldet. Und von der promise API die Argumente für then sind

then(successCallback, errorCallback, notifyCallback) 

das heißt die dritte Rückruffunktion notifyCallback für jede Iteration von $interval genannt wird. So ist der Test wie folgt aussehen würde:

it('should set promiseCalled', function(){ 
    var promiseCalled = false; 
    dice.rollDice().then(null, null, function() { 
    promiseCalled = true; 
    }); 
    $interval.flush(100); 
    $rootScope.$apply(); 
    expect(promiseCalled).toBe(true); 
}); 

Wenn Sie einen aufgelöst Versprechen testen wollen, dann wäre es in etwa so aussehen:

it('should resolve promise', function(){ 
    var promiseCalled = false; 
    var resolvedData = null; 
    $q.when('Some Data').then(function(data) { 
    promiseCalled = true; 
    resolvedData = data; 
    }); 
    $rootScope.$apply(); 
    expect(promiseCalled).toBe(true); 
    expect(resolvedData).toBe('Some Data'); 
}); 

ich die Plunker mit diesen Test aktualisiert haben Fälle.

+1

Aaaahhhh .... danke. Im vorherigen Code hatte ich '$ interval.flush', aber das' $ rootScope. $ Apply' ist etwas Neues .... – Kendall

+0

Ich weiß nur, dass diese Frage während der Lösung eines Problems keine passende Frage beantwortet .... Wie Ich teste das * Versprechen Callback * Event Return von '$ interva()' – Kendall

+1

@Kendall aktualisierte Antwort, um Ihren letzten Kommentar zu adressieren – user2718281