IamaC
IamaC

Reputation: 377

How do I mock a method of a mocked module with Jest?

I am trying to mock the 'dialog' in electron module using jest and running into issues below. When setting up the mock directly on the object it is working(case 1). However when storing the mock function in a variable and setting that in the mock object fails(case 2). Any input why this is the case? I am new to jest and js in general. However I thought these two cases should behave the same.

Case 1: Working

jest.mock('electron', () => ({
  dialog: {
    showOpenDialog: jest.fn(()=>({filePaths:['']})),
  },
}));

Case 2: Not working. Error: TypeError: electron_1.dialog.showOpenDialog is not a function

const showOpenDialogMock = jest.fn(()=>({filePaths:['']}));
jest.mock('electron', () => ({
  dialog: {
    showOpenDialog: showOpenDialogMock,
  },
}));

Test:

test("Menu click", async () => {   

    const setDirMenuItem = subMenu.getSetProjectDirSubMenu(
      <any>mainWindow,
      <any>projectSettings
    );
    await setDirMenuItem.click();
    expect(showOpenDialogMock).toHaveBeenCalledTimes(1);
  }
  );

Code in test:

export const getSetProjectDirSubMenu = (
  mainWindow: BrowserWindow,
  projectSettings: ProjectSettings
) => ({
  label: 'Set Project Directory',
  click: async () => {
    const result = await dialog.showOpenDialog(mainWindow, {
      properties: ['openDirectory'],
      defaultPath: projectSettings.getProjectDir()
    });

    if (result.filePaths[0]) {
      projectSettings.setProjectDir(result.filePaths[0]);
      mainWindow.webContents.send('PROJECT_DIRECTORY_SET', {});
    }
  }
});

Thanks in advance.

Upvotes: 1

Views: 2028

Answers (1)

Michael Lee
Michael Lee

Reputation: 282

jest.mock calls are moved to the top of the file (hoisted). So in Case 2, the mock is created before const showOpenDialogMock is defined.

The code that actually runs looks more like:

jest.mock('electron', () => ({
  dialog: {
    showOpenDialog: showOpenDialogMock,
  },
}));
const showOpenDialogMock = jest.fn(()=>({filePaths:['']}));

Knowing that, here's what you might try instead:

import {dialog} from 'electron';

jest.mock('electron', () => ({
  dialog: {
    showOpenDialog: jest.fn(()=>({filePaths:['']})),
  },
}));

test("Menu click", async () => {   
  const setDirMenuItem = subMenu.getSetProjectDirSubMenu(
    <any>mainWindow,
    <any>projectSettings
  );
  await setDirMenuItem.click();
  // note: dialog.showOpenDialog
  expect(dialog.showOpenDialog).toHaveBeenCalledTimes(1);
});

More on module functions and mocking modules from Jest documentation.

Upvotes: 2

Related Questions