Reputation: 621
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
Upvotes: 1
Views: 8566
Reputation: 4033
You are passing your mocked function to Products
via a click
prop which the component doesn't receive/expect 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();
});
Upvotes: 2