2015-10-29 19 views
13

我一直在從this tutorial工作,並有谷歌搜索廣告的噁心,但我似乎無法得到似乎是一個微不足道的單元測試運行ngAnimatengAnimate 1.4.7單元測試不調用動畫函數

我有ngAnimate在應用程序中運行良好。所有的Angular核心庫都是1.4.7版本。

模塊

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

測試

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' 

我敢肯定,該模塊被包括在測試,但觸發$animate.enter甚至不把我的log輸出。

我已經嘗試過與其他$animate函數一起使用,並且我無處可去。幫幫我?

回答

9

在對Angular的源代碼進行了一些認真的挖掘之後,看來罪魁禍首是Angular用於確定是否儘早中止動畫的內部檢查areAnimationsAllowed。其中,檢查正在動畫的節點是$rootElement和文檔正文的後代。

您有兩種選擇。

  1. Plunker將您正在動畫的節點附加到$rootElement,並將$rootElement附加到主體。後者是必需的,因爲ngMock實際上存根$rootElement與在內存中保存的獨立的<div>節點。 實施例:
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); 
}); 
  • Plunker。請勿使用$animate.addClass測試動畫,而應使用使用較低級$$animateJs服務。 Angular使用它inside their own tests,我假設繞過上面的檢查。 例子:
  • it('should animate', inject(function ($animate, $$animateJs) { 
        // trigger animation 
        $$animateJs(element, 'addClass', { 
        addClass: 'added-class' 
        }).start(); 
        $animate.flush(); 
    })); 
    

    如果運行Plunkers和檢查控制檯,你會看到你的 「addClass觸發」 的消息。我還添加了幾個斷言。

    這兩種解決方案都很不健全,如果你的動畫做了一些異步操作(我認爲它會),這兩種解決方案都會變得更加複雜。不幸的是,我找不到更好的方法來測試JS動畫。在過去,我實際上忽略了覆蓋範圍內的動畫代碼,因爲它很難測試。

    相關問題