问题::运行代码时,SVG会附加到组件的外部div上,并完美地呈现在页面上。但是,在测试期间,SVG不会附加到外部div。
堆栈:我正在尝试使用Jest / Enzyme测试包装在React组件中的d3js元素。
我到目前为止所做的研究:查找了有关使用google测试d3js以及stackoverflow的大量指南。使用了有关对d3js和React with Jasmine进行单元测试的指南。我还读到,用Enzyme测试第三方库可能很困难,因此这可能是测试框架的局限性。
我提供了一个基本的代码示例进行测试。
组件:
import React from "react";
import * as d3 from "d3";
export default class Circle extends React.Component {
componentDidMount = () => {
return this.renderCircle();
}
renderCircle = () => {
d3.select("#outerDiv")
.append("svg")
.attr("width", 600)
.attr("height", 300)
.append("circle")
.attr("id", "d3-el")
.attr("cx", 300)
.attr("cy", 150)
.attr("r", 30)
.attr("fill", "#ff0000")
.on("click", function (d, i) {
var item = d3.select(this);
item.attr("fill", "#00ff00");
});
}
render() {
return <div id="outerDiv" />;
}
}
测试:
import React from "react";
import * as d3 from "d3";
const jsdom = require("jsdom");
const ReactJSDOM = require('react-jsdom');
const { JSDOM } = jsdom;
import Circle from "./Circle.js";
import { mount } from "enzyme";
import sinon from 'sinon';
describe("Circle", () => {
it("d3js element should be appended to outer div", () => {
let wrapper = mount(<Circle />);
let instance = wrapper.instance();
const jsdomElem = ReactJSDOM.render(<html><body><p><Circle /></p></body></html>);
console.log(jsdomElem.querySelector("#d3-el")); // returns null
console.log(wrapper.find("d3-ele").get(0));; // returns undefined
console.log(d3.select("d3-el")); // returns null
expect(wrapper.find("d3-el").exists()).toEqual(true);
}
}
在应该使用wrapper.find(),document.querySelector()和d3.select()呈现的d3元素上进行查找都返回undefined或null。
我尝试过但未将SVG元素附加到外部div的操作:
在组件上使用mount()。
使用已安装组件的instance()并直接调用renderCircle()方法。
使用ReactJSDOM从顶部到底部渲染整个DOM。
一堆其他可能毫无意义的东西,包括sinon.spy()和嘲笑jest.fn()。
这些方法都不起作用,如果我在外部div上进行查找,则不会显示div有任何子元素。在包装器上进行调试会显示相同的结果。
在测试过程中,希望将SVG附加到div上会有帮助。任何解决方案或其他策略将不胜感激。如果您有任何疑问或需要添加更多信息,请告诉我。谢谢!
答案 0 :(得分:1)
首先,您应该将组件的关注点分开。
将与d3相关的代码移动到单独的函数(或类)中,并像测试其他任何React组件一样测试组件。
答案 1 :(得分:0)
当我使用d3js和Jest做类似的事情时,我遇到了这个问题。我正在执行d3.select(#id)
,其中id已通过
barGraphContainer = document.createElement("div");
barGraphContainer.id = "testBar_d3";
barGraphContainer.setAttribute(
"style",
"width: 1024px; height: 400px;"
);
document.body.appendChild(barGraphContainer);
在jest.environment.setup.js
中,我添加了以下内容以将d3搜索到的文档与JSm文档绑定在一起。
const JSDOM = require("jsdom").JSDOM;
const jsdom = new JSDOM(`<!doctype html><html lang="en"><body></body></html>`);
global.window = jsdom.window;
global.document = jsdom.window.document;