1

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.

2 Answers 2

4

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();
  });
});

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

6 Comments

Thanks for the answer, but in my case, I just imported it from another file, and I tested this function separately.
So did it work or still looking for answers? @RobertHovhannisyan
Nah, still looking for the answer :/
I've added a third case that looks like your use case
Please note that if your component is using other parts from ../path/to/util and you don't want to mock everything, maybe simply do: jest.mock('../path/to/util', () => ({ ...jest.requireActual('../path/to/util'), someFunction: jest.fn() })); ```
|
0

someFunction() needs to generate some side effects to your app. You can test those side effects. For instance if someFunction() was incrementing a count state value you could test for that in your component to check if count was incremented when button was clicked.

3 Comments

Thanks for the option, but I forgot to mention that I can't measure any state change, because it doesn't give any side effects
What exactly is someFunction() doing in your application ?
It creates a blob

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.