D3js в модульном тестировании компонентов React с использованием Jest / Enzyme - PullRequest
2 голосов
/ 11 марта 2019

Проблема: Когда я запускаю свой код, SVG добавляет к внешнему div на компоненте и прекрасно отображает на странице.Однако во время тестирования SVG не добавляется к внешнему div.

Stack: Я пытаюсь проверить мой элемент d3js, заключенный в компонент React, с помощью Jest / Enzyme.

Исследования, которые я провел до сих пор: Посмотрел кучу руководств / постов по тестированию d3js с помощью Google и на 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);
    }
}

Выполнение поиска элемента d3, который должен быть визуализирован с использованием wrapper.find (), document.querySelector () и d3.select () все возвращают undefined или null.

То, что я пробовал, но не добавляет элемент SVG во внешний div:

  1. Использование mount () для компонента.

  2. Использование instance () смонтированного компонента и прямой вызов метода renderCircle ().

  3. Использование ReactJSDOM для рендеринга всего DOM сверху вниз.

  4. Куча других вещей, которые, вероятно, не имеют смысла, включая sinon.spy () инасмешка над jest.fn ().

Ни один из этих методов не работает, и если я найду внешнююdiv, это не показывает, что у div есть какие-либо дочерние элементы.Выполнение отладки в оболочке показывает то же самое.

Очень хотелось бы получить некоторую помощь для добавления SVG в div во время тестирования.Любые решения или другие стратегии будут с благодарностью.Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы или я должен добавить дополнительную информацию.Спасибо!

1 Ответ

0 голосов
/ 12 марта 2019

Я столкнулся с этой проблемой ранее, когда делал что-то похожее с d3js и Jest.Я выполнял d3.select(#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 и документ JSDom.

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;
...