I have a button click handler in which I call another function. I need to test the function call inside of the handler:
SomeComponent
...
const handler = () => {
someFunction();
}
...
<button data-testId="button" onClick={handler}>Click Me</button>
test
describe('Button click', () => {
it('button click', async () => {
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// some silly test case just for example
expect(button).toBeInTheDocument();
});
});
While doing this, it covers the handler but not the inner function itself:
const handler = () => { <<<<<<< covered
someFunction(); <<<<<<< UNCOVERED
}. <<<<<<< covered
The main question here is how can I test the inner function call? If I need to mock it, how should I do it, because the mocked function will not test the actual one?
UPDATE
Also, my someFunction doesn't change anything in the scope of this component, so I can't catch it by comparing the inner state or document change.
SomeFunction is coming from another file and I tested it separately.
CodePudding user response:
It depends on where someFunction
is defined. If it's a property given to <SomeComponent />
then you could do something like this:
describe('Button click', () => {
it('button click', async () => {
const someFunction = jest.fn();
render(<SomeComponent someFunction={someFunction} />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe
// use `toHaveBeenCalledWith` instead
expect(someFunction).toHaveBeenCalled();
});
});
But if it's defined in a separate hook then you should mock this hook. For instance here let's assume there a useSomeFunction
that directly returns this someFunction
:
import { useSomeFunction } from '../path/to/useSomeFunction';
jest.mock('../path/to/useSomeFunction', () => ({
useSomeFunction: jest.fn(),
}));
describe('Button click', () => {
it('button click', async () => {
const mockSomeFunction = jest.fn();
useSomeFunction.mockImplementation(() => mockSomeFunction);
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe
// use `toHaveBeenCalledWith` instead
expect(mockSomeFunction).toHaveBeenCalled();
});
});
And if it's simply a function defined elsewhere you could adapt the example I gave with hook mocking:
import { someFunction } from '../path/to/util';
jest.mock('../path/to/util', () => ({
someFunction: jest.fn(),
}));
describe('Button click', () => {
it('button click', async () => {
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe
// use `toHaveBeenCalledWith` instead
expect(someFunction).toHaveBeenCalled();
});
});
CodePudding user response:
someFunction()
needs to generate some side effects to your app. You can test those side effects. For instance ifsomeFunction()
was incrementing a count state value you could test for that in your component to check if count was incremented when button was clicked.