question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IPC Main <-> Renderer Example Test

See original GitHub issue

Following the Electron recommendations, I’m removing remote access completely in renderer and convert everything to be IPC via .invoke()

Is it possible to test IPC communication between Main/Renderer via e-mocha ?

If so, could you provide a simple e-mocha test on how to trigger an IPC event from renderer that is then received in main process (or vice versa) ?

I’ve looked through the provided test examples as well as projects that use e-mocha, but did not find a suitable example.

Thanks.

Electron 12.0.2 E-Mocha 9.3.3 Win x64

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10

github_iconTop GitHub Comments

3reactions
inukshukcommented, Apr 21, 2021

If you stub a method, the original method is replaced on the context instance.

In the updated example 1 you allegedly stub a method, yet the original is invoked (there’s console output) so this means my_class (the one you stubbed) is not the same instance as the one that was registered to receive the IPC messages. This is further confirmed by the fact that your stub was not called at all.

In the updated example 2:

  1. You call ipcMain.handle first
  2. Then you create a spy on ipcMain.handle
  3. You don’t call ipcMain.handle again (it is not called on receiving IPC messages either)
  4. So obviously the call count is zero

There is nothing surprising about this. You seem to expect that ipcMain.handle will be invoked when an IPC message is received, but it is not. You set up the handler first (the function you pass as the second argument to ipcMain.handle) and only the handler will be invoked. If you want to stub/spy on the handler you need to create the stub/spy first to make sure that at the moment ipcMain.handle is called it is already the stub/spy that is registered not the original method.

So example 2 looks just fine, but the test makes no sense. Example 1 is a better way to test the fact that the IPC communication took place, but there must be an error in your setup. It looks like you create another My_Class instance somewhere and call its init() method – while the init() method of the My_Class instance which you then use to stub the callback is not called at all.

This test works fine for me (test.html is an empty HTML page):

const { join } = require('path')
const sinon = require('sinon')
const { ipcMain, BrowserWindow } = require('electron')

describe.only('IPC Handlers', () => {
  let spy

  beforeEach(() => {
    spy = sinon.spy()
    ipcMain.handle('test', async () => spy())
  })

  afterEach(() => {
    ipcMain.removeHandler('test')
  })

  it('can be invoked', async () => {
    let win = new BrowserWindow({
      webPreferences: {
        contextIsolation: false,
        nodeIntegration: true
      }
    })

    await win.loadFile(join(__dirname, 'test.html'))

    win.webContents.executeJavaScript(
      `require('electron').ipcRenderer.invoke('test')`
    )

    // Allow some time for the IPC messages to be sent.
    await new Promise((resolve) => setTimeout(resolve, 500))

    win.destroy()

    expect(spy.callCount).to.equal(1)
  })
})
1reaction
inukshukcommented, Apr 22, 2021

In a given process, ipcMain is always the same thing no matter how many times you import/require it. If I’m not mistaken, there can only be a single handler per channel, so it’s no problem to remove your test handler, after a test with using ipcMain.removeHandler(channel).

Read more comments on GitHub >

github_iconTop Results From Across the Web

In case anyone is interested on how to mock ipcRenderer of ...
It simulates ipcRenderer.on() event with the use of RxJS Observables.
Read more >
How to write unit test for ipcRenderer.on and ... - Stack Overflow
Hi I have developing a project using Electron and React,. I have a form in react side which on submit calls the ipcRenderer.on...
Read more >
ipcRenderer - Electron
Communicate asynchronously from a renderer process to the main process. ... The ipcRenderer module is an EventEmitter. It provides a few methods so...
Read more >
IPC Main to IPC Renderer & Back in React.js - Electron S1 E4
Code: https://github.com/keithweaver/ basic -electron-react-boilerplateIn this video, I demo sending messages between the ipc main and ipc ...
Read more >
Inter-Process Communication (IPC) in ElectronJS
ipcRenderer : This Module is used to communicate from the Renderer Processes to the Main Process. It is defined and used in the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found