Ручная имитация реализации вложенного компонента React с помощью jest & энзима - PullRequest
0 голосов
/ 06 ноября 2018

Я проверяю, правильно ли OuterComponent ведет себя, когда его InnerComponent вызывает некоторые вызовы функций. Упрощенный пример:

// js/OuterComponent.js

onInput() {
  // Behaviour to test
}

render() {
  return (
    <div>
      <InnerComponent onInput={() => this.onInput()} />
    </div>
  );
}

Поскольку для того, чтобы InnerComponent наконец вызвал this.props.onInput(), должна произойти довольно сложная цепочка событий, я бы хотел высмеять InnerComponent в своих тестах. Я пытаюсь сделать следующее:

// tests/OuterComponent.test.js

jest.useFakeTimers();

describe("OuterComponent", () => {
  test("behaves correctly when receiving input", () => {
    jest.mock("../js/InnerComponent")
    const wrapper = shallow(<OuterComponent />);
    jest.runAllTimers();
    // expectations about OuterComponent after `onInput` has been called
  });
});

Макет:

// js/__mocks__/InnerComponent.js

export default class SVGSymbolDrawing extends React.Component {
  componentDidMount() {
    setTimeout(() => {
      this.props.onInput();
    }, 100);
  }

  render() {
    return <div/>;
  }
}

Мои expect все терпят неудачу, хотя. Я не вижу никаких console.logs из макета InnerComponent, но я не уверен, как проверить, что он на самом деле использует макет, а не реальный внутренний компонент.

1 Ответ

0 голосов
/ 06 ноября 2018

Вместо насмешки над всем InnerComponent вы можете вызывать эту функцию напрямую, используя wrapper.instance(), то есть вызывая wrapper.instance().onInput()

Полный пример с прохождением теста:

OuterComponent.js

import React, { Component } from "react";
import InnerComponent from "./InnerComponent";

class OuterComponent extends Component {
  onClick() {
    this.setState({ clicked: true });
  }
  render() {
    return <InnerComponent onClick={() => this.onClick()} />;
  }
}
export default OuterComponent;

InnerComponent.js

const InnerComponent = ({onClick}) => <div onClick={onClick}>INNER</div>;
export default InnerComponent;

OuterComponent.test.js

import React from "react";
import Enzyme, { shallow } from "enzyme";
import Adapter from 'enzyme-adapter-react-16';
import OuterComponent from "./OuterComponent.js";

Enzyme.configure({ adapter: new Adapter() });

describe("OuterComponent", () => {
  it("handles onClick", () => {
    const wrapper = shallow(<OuterComponent />);
    wrapper.instance().onClick();
    expect(wrapper.state('clicked')).toBe(true);
  });
});
...