Home > Software engineering >  Test for Button click to call a mocked function fails
Test for Button click to call a mocked function fails

Time:12-05

Attempting to teach myself testing for React with react-testing library and jest as this is what my work uses. For the life of me I can not figure out why the mock function testClick is not being called. I have researched articles and watched videos however most seem outdated as it appears the testing world changes how code should be written super fast. Anyone have thoughts? Here's the code :

Products.js component :

import React, { useState } from 'react';
import { fetchProducts } from '../service';

const Products = () => {
  const [product, setProduct] = useState('');

  const handleSubmit = (event) => {
    event.preventDefault();
    fetchProducts();
  };

  const hasBeenClicked = () => {
    console.log('clicked!');
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        <input
          type="text"
          value={product}
          onChange={(e) => setProduct(e.target.value)}
        />
      </label>
      <input
        type="submit"
        onClick={hasBeenClicked}
        data-testid="button"
        label="Search"
      />
    </form>
  );
};

export default Products;


Products.test.js :

import React from 'react';
import { render, screen, cleanup, fireEvent } from '@testing-library/react';
import Products from './Products';


test('Button click triggers click event', () => {
  const testClick = jest.fn();
  const { getByTestId } = render(<Products click={testClick} />);
  const button = getByTestId('button');
  fireEvent.click(button);

  expect(testClick).toBeCalled();
});

Results in :

 PASS  src/App.test.js
 FAIL  src/components/Products.test.js
  ● Console

    console.log
      clicked!

      at apply (src/components/Products.js:13:13)

  ● Button clicks triggers click event

    expect(jest.fn()).toBeCalled()

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

      11 |   fireEvent.click(button);
      12 |
    > 13 |   expect(testClick).toBeCalled();
         |                     ^
      14 | });
      15 |

      at Object.<anonymous> (src/components/Products.test.js:13:21)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        3.18 s, estimated 4 s

CodePudding user response:

You are passing your mocked function to Products via a click prop which it doesn't receive in the first place. This mocked click function is not wired in any way to the button you're clicking on your test.

To pass this test:

Products.js:

import React, { useState } from "react";
import { fetchProducts } from '../service';

const Products = ({ click }) => {
  const [product, setProduct] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();
    fetchProducts()
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        <input
          type="text"
          value={product}
          onChange={(e) => setProduct(e.target.value)}
        />
      </label>
      <input
        type="submit"
        onClick={click}
        data-testid="button"
        label="Search"
      />
    </form>
  );
};

export default Products;

Products.test.js:

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import Products from "./Products";

test("Button click triggers click event", () => {
  const testClick = jest.fn();
  render(<Products click={testClick} />);
  const button = screen.getByTestId("button");
  fireEvent.click(button);
  expect(testClick).toBeCalled();
});
  • Related