0

I am trying to test a React component. It is an input element that on button click the value is set to "".

My test keeps on failing but I am confused because I can see that it does in fact work on button click.

Heres the test


const mockedSetSearch = jest.fn();
const mockedSearch = "Hello world";


  it("Input should be cleared on 'clear' button click", () => {
    render(
      <PostSearch setUserSearch={mockedSetSearch} userSearch={mockedSearch} />
    );
    const inputElement = screen.getByPlaceholderText(
      /Search posts/i
    ) as HTMLInputElement;
    fireEvent.change(inputElement, { target: { value: "Hello World" } });
    const buttonElement = screen.getByRole("button", { name: /clear/i });
    fireEvent.click(buttonElement);
// LINE BELOW FAILS THE TEST
    expect(inputElement.value).toBe("");
  });

P.S I am using TypeScript + Nextjs

DGB
  • 1,252
  • 2
  • 16
  • 32
  • 1
    I don't know the testing framework, but assuming clicking the button changes the state, is it possible your `expect(inputElement.value).toBe("")` executes before the page has rerendered and the input updated? – DBS Jul 21 '21 at 13:34

1 Answers1

1

You should wrap async stuff like clicks in act. Because hooks and setState are async, so whatever logic you have async too. So test assertion happen before component change value.

Possibly need to use waitFor

Similar question

import { act } from @testing-library/react

it("Input should be cleared on 'clear' button click", () => {
    render(
      <PostSearch setUserSearch={mockedSetSearch} userSearch={mockedSearch} />
    );
    const inputElement = screen.getByPlaceholderText(
      /Search posts/i
    ) as HTMLInputElement;
    act(() => {
      fireEvent.change(inputElement, { target: { value: "Hello World" } });
    })
    const buttonElement = screen.getByRole("button", { name: /clear/i });
    act(() => {
      fireEvent.click(buttonElement);
    })
// LINE BELOW FAILS THE TEST
 //   expect(inputElement.value).toBe("");

    await waitFor(() => {
     expect(inputElement).toHaveValue("");
    });
    // or await waitFor(() => {
    //   expect(screen.getByPlaceholderText(
    //    /Search posts/i
    //  ) as HTMLInputElement).toHaveValue("");
    // });

  });