2017-03-01 80 views
1

我使用jasmine來單元測試d3.js圖表中的一些交互。我一直在使用d3.timerFlush()來完成動畫的執行。這對於輸入新元素或更新屬性非常有用,並且我能夠準確測試新值。但是,我很難讓它去除元素。d3js單元測試刪除元素

我有這樣的方法:

exit() { 
    let arcs = svg.selectAll("path.arc"); 

    arcs.transition().duration(1000) 
     .attrTween("d", function(d, i) { return vm._arcTween(this, d) }) 
     .remove(); 
} 

我的測試看起來是這樣的:

it('it will remove all of the pie related elements from the DOM',() => { 
     chartSvc.exit(); 
     d3.timerFlush(); 
     let elements = svg.querySelectorAll(/* selects my elements */); 
     expect(elements.length).toEqual(0); 
}); 

其失敗。如果我調試測試,我可以看到元素沒有被刪除。但是,如果我改變預期:

expect(pieChartSvc._arcTween).toHaveBeenCalled(); 

即通過,所以我知道這是正常執行的方法和定時刷新,但元素不會被刪除。

我在做什麼錯?

此問題:Disabling all D3 animations (for testing) 不回答我的問題。所述過渡正在執行與該元件已改變成它們在它們從DOM除去之前的狀態,然而,它們仍然出現在DOM

+0

根據[這裏](HTTP://計算器.com/questions/20068497/d3-transition-in-unit-testing),[this](https://stackoverflow.com/questions/14443724/dis abling-all-d3-animations-for-testing),[this](https://github.com/d3/d3/issues/1789)和[this](https://bl.ocks.org/mbostock/) 9644751),你需要在刷新之前設置'Date.now'。 – Mark

+0

我已經試過,因爲它是在這個答案:http://stackoverflow.com/questions/20068497/d3-transition-in-unit-testing,它仍然無法正常工作。動畫正在執行中,並且元素位於新的位置,但它們不會從DOM中移除 – yammerade

+0

誤解,我認爲您在完成轉換運行時遇到問題;恢復了我的關閉。 – Mark

回答

2

好的,計算出來,d3版本3中使用的使用date.now來測量時間。第4版移至performance.now

所以,正確的代碼應該是:

it('it will remove all of the pie related elements from the DOM',() => { 
    chartSvc.exit(); 
    performance.now = function() { return Infinity; }; 
    d3.timerFlush(); 
    let elements = svg.querySelectorAll(/* selects my elements */); 
    expect(elements.length).toEqual(0); 
}); 

下面是一些測試代碼:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    <style> 
 
     path { 
 
     fill: none; 
 
     stroke: steelblue; 
 
     } 
 
    </style> 
 
    </head> 
 

 
    <body> 
 
    <svg width="300" height="300"> 
 
     <g transform="translate(20,20)"> 
 
     <path class="arc" d="M0,0L100,0"></path> 
 
     <path class="arc" d="M0,50L100,50"></path> 
 
     <path class="arc" d="M0,100L100,100"></path> 
 
     <path class="arc" d="M0,150L100,150"></path> 
 
     </g> 
 
    </svg> 
 
    <script> 
 
     
 
     var svg = d3.select('svg'); 
 
     
 
     let arcs = svg.selectAll("path.arc"); 
 
     
 
     arcs.transition() 
 
     .duration(10000) 
 
     .remove(); 
 
      
 
     performance.now = function() { return Infinity; }; 
 
     d3.timerFlush(); 
 

 
    </script> 
 
    </body> 
 

 
</html>

+0

這對我有用。謝謝! – yammerade