简体   繁体   中英

Jest how to call a function from parent component that is passed as a prop to child component

const Parent = () => {
  const [page, setPage] = useState(1);
  const handleSetPage = () => {
    setPage(2);
  };
  return (
    <div>
      {page === 1 && <ChildPage1 handleSetPage={handleSetPage} /> }
      {page === 2 && <ChildPage2  /> }
    </div>
  )
}

const ChildPage1 = ({handleSetPage}) => {
  return (
    <button onClick={handleSetPage}>Next page</button>
  )
}


it('Continues to next page on button click', () =>  {
  render(<CreateDuty />);
  fireEvent.click(screen.getByText('Next page'));
  expect('Page 2 text').toBeInTheDocument();
});

Im trying to test that the pages change when button is clicked, but in the test handleSetPage() isnt being called.

How do I pass/wrap/mock the function so it gets called?

First of all user events are async, which means you need to wrap your test function in an async function and await the user events.

import React, { useState } from 'react'
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

const Parent = () => {
    const [page, setPage] = useState(1);
    const handleSetPage = () => {
        setPage(2);
    };
    return (
        <div>
            {page === 1 && <ChildPage1 handleSetPage={handleSetPage} />}
            {page === 2 && <ChildPage2 />}
        </div>
    )
}

const ChildPage1 = ({ handleSetPage }) => {
    return (
        <button onClick={handleSetPage}>Next page</button>
    )
}

const ChildPage2 = () => {
    return (
        <div>Page 2 text</div>
    )
}

it('Continues to next page on button click', async () => {
    render(<Parent />);
    const button = screen.getByRole('button');
    userEvent.click(button);
    const page2Text = await screen.findByText('Page 2 text');
    expect(page2Text).toBeInTheDocument();
});

second, you need to find the element that you looking for and expect it. If you expect a string you will get this error:

received value must be an HTMLElement or an SVGElement.
Received has type:  string
Received has value: "Page 2 text"

in this example, I get the button by role because there is only one button on the screen. In real-world examples, you can give id 's to components that you want to test and use that id to get the component you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM