admin管理员组

文章数量:1410674

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 ponent, so I can't catch it by paring the inner state or document change.

SomeFunction is ing from another file and I tested it separately.

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 ponent, so I can't catch it by paring the inner state or document change.

SomeFunction is ing from another file and I tested it separately.

Share Improve this question edited Jul 29, 2022 at 13:14 Robert Hovhannisyan asked Jul 29, 2022 at 12:51 Robert HovhannisyanRobert Hovhannisyan 3,3706 gold badges24 silver badges51 bronze badges
Add a ment  | 

2 Answers 2

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

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 ponent to check if count was incremented when button was clicked.

本文标签: javascriptTest the function inside click handlerJestReact testing LibraryStack Overflow