I'm trying to called a mock function using the onClick attribute, testing with React Testing Library. Testing is something I'm trying to improve, but from what I understand so far with what I have.
What I'm testing is that a function is called when the button is clicked, I'm rendering the component (styled component) which is being passed the function as a prop.
(The function it self is asynchronous, but because I'm just mocking that a function is being called on the button I'm just using getBy)
Test file
import { render, screen, fireEvent } from "@testing-library/react";
import QuoteButton from "../Components/QuoteButton";
test("fire event from QuoteButton component", () => {
const mockCollect = jest.fn();
render(<QuoteButton onClick={mockCollect}>get a quote</QuoteButton>);
const buttonElement = screen.getByRole("button", { name: /get a quote/i });
fireEvent.click(buttonElement);
expect(mockCollect).toHaveBeenCalledTimes(1);
});
Component
import styled from 'styled-components'
const StyledButton = styled.button`
cursor: pointer;
background: transparent;
font-size: 18px;
border-radius: 3px;
border-color: #f9a800;
&:hover {
background-color: #ff7800;
color: #fbfbf8
}
`
const QuoteButton = ({ children, collect }) => {
return <StyledButton data-testid="quoteButton" onClick={collect}>{children}</StyledButton>
}
export default QuoteButton
It is receiving 0 number of calls, is there something else I should be looking for or testing? Any help appreciated. My understand is that because i'm mocking a function with jest.fn() then something must be coming through.
CodePudding user response:
You have a prop called collect
that's not being passed in your test, instead you're using onClick
.
import { render, screen, fireEvent } from "@testing-library/react";
import QuoteButton from "../Components/QuoteButton";
test("fire event from QuoteButton component", () => {
const mockCollect = jest.fn();
{/* Wrong: QuoteButton uses 'collect' as a prop */}
// render(<QuoteButton onClick={mockCollect}>get a quote</QuoteButton>);
{/* Right: collect will be the prop passed to your internal component's 'onClick' */}
render(<QuoteButton collect={mockCollect}>get a quote</QuoteButton>); // -->
const buttonElement = screen.getByRole("button", { name: /get a quote/i });
fireEvent.click(buttonElement);
expect(mockCollect).toHaveBeenCalledTimes(1);
});
In the original code you define in your <QuoteButton>
a collect
prop and then passes it to your <button>
's onClick, you're basically saying: onClick -> call collect's reference, please.
Since in your spec you don't send anything to collect to <QuoteButton>
, it has nothing to call in your spec. Also, since you don't do anything with the received onClick
, it changes nothing, too.