jeudi 10 septembre 2020

How to test child components click event effects on parent component?

I am trying to simulate a click event inside the Button-component that hides the Button-component.


Clicking the button will make a call to the fetch()-method inside App-component, then the Redux stuff happening in the background will return an array of posts, named "posts".

The {posts.length === 0 && <SharedButton {...configButton} />} part will render the Button-component if the posts-array is empty and thus it will disappear once the data is loaded into the posts-array.


I already have a shallow render wrapper for App inside App.test.js, and I tried to drill through the wrapper to the Button-component and I did find it with setup().childAt(1).childAt(1).dive(), but when I tried to simulate the event, the call did not register in Jest, even though the console.log("submitEvent"); was shown on the console, which means that the call was actually done.

Button-component:

    import React, { Component } from "react";
    import PropTypes from "prop-types";

    class SharedButton extends Component {

    constructor(props) {
      super(props);
      this.submitEvent = this.submitEvent.bind(this);
    }

    submitEvent() {
      if (this.props.emitEvent) {
        this.props.emitEvent();
        console.log("submitEvent");
      }
    }

    render() {
      const { buttonText } = this.props;

      return (
        <button onClick={this.submitEvent} data-test="buttonComponent">
          {buttonText}
        </button>
      );
    }
    }

    SharedButton.propTypes = {
      buttonText: PropTypes.string,
      emitEvent: PropTypes.func,
    };

    export default SharedButton;

App-component:

import React, { Component } from "react";
import Header from "./components/header";
import Headline from "./components/headline";
import SharedButton from "./components/button";
import ListItem from "./components/listitem";
import { connect } from "react-redux";
import { fetchPosts } from "./actions";
import "./app.scss";

const tempArr = [
  {
    fName: "John",
    lName: "Doe",
    email: "john@doe.com",
    age: 25,
    onlineStatus: true,
  },
];

class App extends Component {
  constructor(props) {
    super(props);
    this.fetch = this.fetch.bind(this);
  }

  fetch() {
    this.props.fetchPosts();
  }

  render() {
    const configButton = {
      buttonText: "Get posts",
      emitEvent: this.fetch,
    };

    const { posts } = this.props;

    return (
      <div className="App" data-test="appComponent">
        <Header />
        <section className="main">
          <Headline
            header="Posts"
            desc={posts.length === 0 ? "Click the button to render posts!" : ""}
            tempArr={tempArr}
          />
          {posts.length === 0 && <SharedButton {...configButton} />}
          {posts.length > 0 && (
            <div>
              {posts.map((post, index) => {
                const { title, body } = post;
                const configListItem = {
                  title,
                  desc: body,
                };
                return <ListItem key={index} {...configListItem} />;
              })}
            </div>
          )}
        </section>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    posts: state.posts,
  };
};

export default connect(mapStateToProps, { fetchPosts })(App);

App.test.js:

import React from "react";
import App from "./App";
import { shallow } from "enzyme";
import { findByTestAtr, testStore } from "../utils";

const setup = (initialState = {}) => {
  const store = testStore(initialState);
  const wrapper = shallow(<App store={store} />)
    .childAt(0)
    .dive();
  return wrapper;
};

describe("App component", () => {
  let wrapper;

  beforeEach(() => {
    const initialState = {
      posts: [
        {
          title: "test title 1",
          body: "test body 1",
        },
        {
          title: "test title 2",
          body: "test body 2",
        },
        {
          title: "test title 3",
          body: "test body 3",
        },
      ],
    };
    wrapper = setup(initialState);
  });

  test("Should render without errors", () => {
    const component = findByTestAtr(wrapper, "appComponent");
    expect(component.length).toBe(1);
  });
});

In a nutshell, the test I want to write is "Button component should not render after click event".

Aucun commentaire:

Enregistrer un commentaire