Test a onClose callback from dialog when using material UI & react testing library?

Viewed 5328

I'm currently trying to get complete test coverage on my react app however I'm stuck with jest when trying to test the callback event params from material UI components.

I thought by testing the escape event I could cover the onClose parameter but it is still showing as untested.

Example of that test:

function renderWithRedux(
  ui: any,
  startingState: any = initialState,
  store?: any
) {
  if (!store) {
    store = createStore(reducer, startingState);
  }
  return {
    ...render(<Provider store={store}>{ui}</Provider>),
    // adding `store` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    store,
  };
}


test("Should close the dialog on exit event eg esc key pressed", () => {
  const { container, queryByTestId } = renderWithRedux(
    <PermissionGroupList />,
    permissionGroupCat
  );
  fireEvent(
    queryByTestId("add-group"),
    new MouseEvent("click", {
      bubbles: true,
      cancelable: true,
    })
  );
  let dialogBox = queryByTestId("add-group-dialog");

  // Check that the dialog is open.
  expect(dialogBox).toBeTruthy();
  // Check that the dialog it closes.
  fireEvent.keyDown(document.body, {
    key: "Escape",
    keyCode: 27,
    which: 27
  })
  setTimeout(() => {
    // Try to re get the element.
    dialogBox = queryByTestId("add-group-dialog");
    expect(dialogBox).toBeNull();
  }, 500);
})

Same or similar issue when passing the bound closeDialog method to the child component. It appears as untested. How would I test this / will it be covered with the tests of the children component if it fires the method (on the child), I have not yet created the child component tests.

enter image description here

As you can see in the screenshot above both these lines come back as untested, so how do I cover these with my tests.

I'm using react-testing-library and jest --coverage with redux and react-redux.

2 Answers

Your running async code in a sync test. If you use setTimeout in your test then you need to pass in a done() function and then call it when your last async event has finished.

https://jestjs.io/docs/en/asynchronous

I recommend not creating arrow functions as props. Here's a more detailed explanation of the the drawbacks and alternate approaches: https://medium.com/@oleg008/arrow-functions-in-react-f782d11460b4

This would also make it so those props would be covered by your tests. Though you may also need to test that the class method handleGroupDialog is called. You can do this with a spy: https://remarkablemark.org/blog/2018/06/13/spyon-react-class-method/

David is also right! You'll want to use a done method or convert your test to async and await.

Related