2015-10-29 16 views
13

Ho lavorato da this tutorial e ho cercato su Google fino alla nausea, ma non riesco a ottenere quello che sembra essere un banale test delle unità ngAnimate in esecuzione.ngAnimate 1.4.7 unit test non chiama le funzioni di animazione

Ho il ngAnimate che funziona bene nell'app. Tutte le librerie di base angolari sono la versione 1.4.7.

modulo

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

prova

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' 

Sono sicuro che il modulo è stato incluso nel test, ma innescando $animate.enter non ha nemmeno a ottenere la mia log uscita .

Ho provato questo con altre funzioni $animate e sto arrivando da nessuna parte. Aiuto?

risposta

9

Dopo aver scavato seriamente nel codice sorgente di Angular, sembra che il colpevole sia il controllo interno areAnimationsAllowed che Angular utilizza per determinare se interrompere anticipatamente l'animazione. Tra le altre cose, lo controlla che il nodo che si sta animando sia un discendente di $rootElement e il corpo del documento.

Hai due opzioni qui.

  1. Plunker. Collegare il nodo che si sta animando a $rootElement e collegare lo $rootElement al corpo. Quest'ultimo è necessario perché ngMock in realtà stub $rootElement con un nodo distaccato <div> tenuto in memoria. Esempio:
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. Non testare l'animazione utilizzando $animate.addClass, ma invece utilizzare il servizio di livello inferiore $$animateJs. Angular lo usa inside their own tests, presumo per aggirare il controllo di cui sopra. Esempio:
it('should animate', inject(function ($animate, $$animateJs) { 
    // trigger animation 
    $$animateJs(element, 'addClass', { 
    addClass: 'added-class' 
    }).start(); 
    $animate.flush(); 
})); 

Se si esegue il Plunkers e verificate la console, si dovrebbe vedere il messaggio "addClass attivato". Ho anche aggiunto un paio di affermazioni.

Entrambe le soluzioni sono hacky e non documentate, ed entrambe diventano più coinvolte se l'animazione addClass fa qualcosa di asincrono (che presumo che lo farà). Sfortunatamente, non riesco a trovare un modo migliore per testare le animazioni JS. In passato ho ignorato il codice di animazione dalla copertura perché è così difficile da testare.