2

Attempting to test a basic react component that takes an event handler onClick. When passing in jest.fn() the tests fails on expect(myComponent).toHaveBeenCalledTimes(1). I'm attempting to simulate a user click with:

const button = document.querySelector("#calcButton");
button.dispatchEvent(new MouseEvent("click", { bubbles: true }));

Full code below.

The app works correctly in prod and dev and document.querySelector("#calcButton").dispatchEvent(new MouseEvent("click", { bubbles: true })); works in the chrome console.

EDIT: Same result if I replace dispatchEvent(...) with .click(). Passing in console.log("Call back activated") as clicked showed that the callback is indeed getting called.

// calculate-button.test.js
import React from "react";
import { act } from "react-dom/test-utils";
import { render, unmountComponentAtNode } from "react-dom";

import Button from "react-bootstrap/Button";
import CalculateButton from "./calculate-button";
let container = null;

beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

// Omitted afterEach and some other tests. The problem occurs with them commented out.

it("fires event when clicked.", () => {
  const clicked = jest.fn();
  act(() => {
    render(<CalculateButton onClick={clicked} />, container);
  });
  const button = document.querySelector("#calcButton");
  console.log(button); // Output indictates button is being selected as hoped.
  act(() => {
    button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
  });

  expect(clicked).toHaveBeenCalledTimes(1);
  // This is where the error happens.
});

//calculate-button.js
import React from "react";
import Button from "react-bootstrap/Button";

function calculateButton(props) {
  return (
    <Button
      variant="primary"
      size="lg"
      id="calcButton"
      block
      onClick={props.handleClick}
    >
      Calculate!
    </Button>
  );
}

export default calculateButton;

The result of npm test

  ● Console

    console.log src/components/calculate-button/calculate-button.test.js:36
      HTMLButtonElement {
        '__reactInternalInstance$vwtourl9fj':
         FiberNode {
           tag: 5,
           key: null,
           elementType: 'button',
           type: 'button',
           stateNode: [Circular],
           return:
...OMITTED...

  ● fires event when clicked.

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

      39 |   });
      40 | 
    > 41 |   expect(clicked).toHaveBeenCalledTimes(1);
         |                   ^
      42 | });
      43 | 

      at Object.toHaveBeenCalledTimes (src/components/calculate-button/calculate-button.test.js:41:19)

Test Suites: 1 failed
4
  • stackoverflow.com/a/46211877/10431732 Commented Sep 2, 2019 at 5:10
  • have you tried button.click() Commented Sep 2, 2019 at 5:10
  • Thanks, @MattOestreich. I'll check that out. I do think it's to do the jest.fn() since passing in other functions to onClick=proves they're being called. Commented Sep 2, 2019 at 18:15
  • button.click() produces the same result. Commented Sep 2, 2019 at 18:16

1 Answer 1

1

Figured it out. Thanks for all the help.

In calculate-button.js I reference onClick={props.handleClick} but in calculate-button.test.js I was passing in the mockClickHandler as the prop onClick. Changing the mismatch by altering render(<CalculateButton onClick={clicked} />, container); to render(<CalculateButton hadleClick={clicked} />, container); fixed it.

That's what I get for sloppy naming. Thanks again.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.