如何用mocha测试d3.js?

时间:2017-05-09 20:57:45

标签: javascript d3.js mocha

我有一个调用d3.js的脚本,然后尝试读取csv:

var d3      = require ("./../../librairies/d3.v2.js")
d3.csv  (   path_to_read, function(data , error)

当我使用mocha对其进行测试时,d3无法执行任何XML请求:

 ReferenceError: XMLHttpRequest is not defined
      at d3_xhr (d3.v2.js:1936:114)

如何用mocha包含和测试d3(我对Mocha很新)?

1 个答案:

答案 0 :(得分:1)

您的第一个问题是Node.js中没有某些对象,因为Node.js不是Web浏览器。其中一个对象是XMLHttpRequest对象。您可以找到一个可以在Node.js中使用此对象的库,但我不建议您这样做。

你的第二个问题是D3有时会导致难以测试代码。

为避免这种情况,您需要以易于测试的方式编写D3代码。所以而不是:

d3.csv(path_to_read, function(data, error) {
   // all your code goes here
})

您需要以下内容:

// some pure functions (data in d3 elements out)
function renderAxis(data) {
    return {};
}

function renderData(data) {
    return {};
}

function renderSomethingElse(data) {
    return {};
}

// one pure function that uses all the other pure functions
// returns a function that needs to be invoked when data finishes loading
function renderEverything(renderAxisFunc, renderDataFunc, renderSomethingElseFunc) {
   return onDataLoaded(data, error) {
      var axis = renderAxisFunc(data);
      var dataPoints = renderAxisFunc(data);
      var somethingElse = renderSomethingElseFunc(data);
      return {
          axis: axis,
          dataPoints: dataPoints,
          somethingElse: somethingElse
      };
   }
}

// Finally you can use the pure functions
d3.csv(path_to_read, function(data, error) {
   var dataLoaded = renderEverything(renderAxis, renderData, renderSomethingElse)
   var chartElements = dataLoaded(data, error);
   // append chartElements
})

如果你写的有纯函数测试变得微不足道:

expect(renderAxis([{/* some mock data */}])).to.eq(/* expected d3 objects*/);
expect(renderData([{/* some mock data */}])).to.eq(/* expected d3 objects*/);
expect(renderSomethingElse([{/* some mock data */}])).to.eq(/* expected d3 objects*/); 

你也可以测试一个大的:

var dataLoaded = renderEverything(
    (data) => { /* mock response */ },
    (data) => { /* mock response */ },
    (data) => { /* mock response */ }
);

expect(data([{/* some mock data */}], false)).to.eq(/* expected d3 objects*/);