reactjs - 使用 Jest/Enzyme 进行 React 组件单元测试中的 D3js

标签 reactjs d3.js jestjs enzyme jsdom

问题:当我运行代码时,SVG 附加到组件上的外部 div 并在页面上完美呈现。但是,在测试过程中,SVG 并未附加到外部 div。

Stack:我正在尝试使用 Jest/Enzyme 测试包装在 React 组件中的 d3js 元素。

我到目前为止所做的研究:查找了一堆关于使用 google 和 stackoverflow 测试 d3js 的指南/帖子。使用了有关 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 的事情:

  1. 在组件上使用 mount()。

  2. 使用已挂载组件的instance()并直接调用renderCircle()方法。

  3. 使用ReactJSDOM从上到下渲染整个DOM。

  4. 一堆其他可能没有意义的东西,包括 sinon.spy() 和 mock jest.fn()。

这些方法都不起作用,如果我在外部 div 上进行查找,它不会显示该 div 有任何子元素。在包装器上进行调试显示了同样的结果。

希望得到一些帮助,以便在测试期间将此 SVG 附加到 div 中。任何解决方案或其他策略将不胜感激。如果您有任何疑问或我是否应该添加更多信息,请告诉我。谢谢!

最佳答案

首先,您应该分离组件的关注点。

将 d3 相关代码移至单独的函数(或类)中,并像测试任何其他 React 组件一样测试您的组件。

之后,测试D3相关的功能。看一下 D3 库本身的测试,例如 here 。他们使用jsdom模拟真实 DOM 的行为。

关于reactjs - 使用 Jest/Enzyme 进行 React 组件单元测试中的 D3js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55104250/

相关文章:

javascript - 如何在用 d3 绘制的 SVG map 上显示国家名称标签?

error-handling - 用 Jest 捕捉错误时如何测试 Redux-Saga

css - 更改material-ui中Grid Item堆叠的顺序

javascript - JSX 中的 eslint "parsing error: Unexpected token {"

reactjs - NextJS Typescript 布局提示缺少 props

javascript - 如何在超测失败时打印请求日志(如请求 url、请求正文、请求 queryParam)?

jestjs - 开 Jest createSpyObj

reactjs - 使用 React Redux 的通用组件

javascript - d3访问分组条形图中的嵌套数据

javascript - 渲染 d3.js html 表而不阻塞 UI