'How to mock and check that a function from a library in Jest framework?

I have a button with "Download" text on it defined in ReactJS code. Now, I want to write a unit test to check that this function is getting called when this button is clicked. I wrote a unit test but it is not working.

import * as FileSaver from "file-saver"
  it('File has to be saved when clicked on the "Download" button', () => {
    jest.mock('file-saver', ()=>({saveAs: jest.fn()}));
    fireEvent.click(component.getByText("Download"));
    expect(FileSaver.saveAs).toBeCalled();
  })

I'm getting this error:

Error: expect(received).toBeCalled()
Matcher error: received value must be a mock or spy function
Received has type:  function
Received has value: [Function anonymous]

pointing to expect(FileSaver.saveAs).toBeCalled(); line.

What's wrong?



Solution 1:[1]

So, as I stated in the comment, you have to move jest.mock('file-saver', ()=>({saveAs: jest.fn()})) from the body of the test to the top of the file, just under the imports. The reason for it is actually answered in the documentation here, but to wrap it up:

In your test file you are using import statement which fires up at start, before any code has a chance to run. Then you try to mock file-saver, but it is already imported with real implementation, not mocked. If you instruct jest to mock module at top of the file it will automatically hoist jest.mock calls to the top of the module so your function exportToExcel will receive mocked file-saver instead of the real one.

But if you really want to mock file-saver in the body of the test for some strange reason you would need to mock file-saver, then include all modules in test which use file-saver, something like this:

it('File has to be saved when clicked on the Export button', () => {
    jest.mock('file-saver', ()=> ({ saveAs: jest.fn() }));
    const component = require('/path/to/tested/componetn/on/which/click/event/is/fired');
    const FileSaver = require('file-saver');

    fireEvent.click(component.getByText("Download"));

    expect(FileSaver.saveAs).toBeCalled();
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Light Yagami