2015-10-29 14 views
13

Ich habe von this tutorial gearbeitet und habe Google nicht geortet, aber ich kann nicht scheinen, was zu einem trivialen ngAnimate Unit-Test läuft.ngAnimate 1.4.7 Komponententest nicht aufrufen Animationsfunktionen

Ich habe ngAnimate funktioniert gut in der App. Alle Angular Core-Bibliotheken sind Version 1.4.7.

Modul

angular.module 'MyAnimation', [ 'ngAnimate' ] 
    .animation '.added-class', -> 
    addClass: (element, className, done) -> 
     console.log 'add class triggered' 
     element.css 'opacity', '0.5' 
     done() 

-Test

describe 'MyAnimation', -> 
    beforeEach -> module 'ngAnimate' 
    beforeEach -> module 'ngAnimateMock' 
    beforeEach -> module 'MyAnimation' 

    it 'animates', -> inject ($animate, $rootScope, $rootElement) -> 
    $animate.enabled(true) 
    divElement = angular.element '<div>my div</div>' 

    # Kick off initial digest loop in which no animations are run. 
    $rootScope.$digest() 

    # Trigger animation. 
    $animate.addClass divElement, 'added-class' 
    $rootScope.$digest() 

    # Tried this, doesn't seem to do anything. 
    # $animate.flush() 

    # Results in AssertionError: expected '' to equal '0.5' 
    expect(divElement.css('opacity')).to.eq '0.5' 

Ich bin sicher, dass das Modul in den Test einbezogen wird, aber $animate.enter Auslösung auch Sie mich nicht meine log Ausgang .

Ich habe dies mit anderen $animate Funktionen auch versucht und komme nirgendwohin. Hilfe?

Antwort

9

Nach einigen ernsthaften Graben in Angulars Quellcode scheint es, dass der Übeltäter die interne Prüfung areAnimationsAllowed ist, die Angular verwendet, um festzustellen, ob die Animation vorzeitig abgebrochen werden soll. Unter anderem überprüft es , dass der Knoten, der animiert wird, ein Nachkomme des $rootElement und des Dokumententexts ist.

Sie haben hier zwei Möglichkeiten.

  1. Plunker. Hängen Sie den Knoten, den Sie animieren, an $rootElement an und befestigen Sie den $rootElement am Körper. Letzteres ist notwendig, weil ngMock tatsächlich Stubs $rootElement mit einem gelöschten <div> Knoten im Speicher gehalten wird. Beispiel:
var element, body, root; 
beforeEach(module('ngAnimate', 'ngAnimateMock', 'MyAnimation')); 
beforeEach(inject(function ($animate, $document, $rootElement, $rootScope) { 
    // enable animations globally 
    $animate.enabled(true); 

    // create a node to be animated and inject it into the DOM 
    element = angular.element('<div></div>'); 
    root = $rootElement.append(element)[0]; 
    body = $document[0].body; 
    body.appendChild(root); 

    // trigger initial digest 
    $rootScope.$digest(); 
})); 
afterEach(function() { 
    // clean up 
    body.removeChild(root); 
}); 
  1. Plunker. Testen Sie Ihre Animation nicht mit $animate.addClass, sondern verwenden Sie den untergeordneten $$animateJs Service. Angular verwendet es inside their own tests, gehe ich davon aus, die obige Prüfung zu umgehen. Beispiel:
it('should animate', inject(function ($animate, $$animateJs) { 
    // trigger animation 
    $$animateJs(element, 'addClass', { 
    addClass: 'added-class' 
    }).start(); 
    $animate.flush(); 
})); 

Wenn Sie die Plunkers und überprüfen Sie die Konsole ausführen, sollten Sie sehen Ihre "addClass ausgelöst" -Meldung. Ich habe auch ein paar Behauptungen hinzugefügt.

Beide Lösungen sind hacky und undokumentiert, und beide werden mehr beteiligt, wenn Ihre addClass Animation etwas asynchrones tut (was ich annehmen werde). Leider kann ich keine bessere Möglichkeit finden, JS-Animationen zu testen. In der Vergangenheit habe ich Animationscode aus der Berichterstattung ignoriert, weil es so schwer zu testen ist.