can 'no-unbound-method' be whitelisted for unittests? Is there any possibility of me facing an issue in future because of whitelisting
Asked Answered
P

3

6

Example:

class MyClass {
  public log(): void {
    console.log(this);
  }
}

unittests.js

const instance = new MyClass();
expect(instance.log).toHaveBeenCalled(); 

Avoid referencing unbound methods error has been thrown while tried to unit test. Is it better to go with arrow functions rather than adding a 'whitelist' option in linting. Any help would be greatly appreciated

Primine answered 2/12, 2019 at 7:6 Comment(0)
B
12

TypeScript flags this because your original function references this. Note that TypeScript doesn't know about jest, and the mock or spy that (presumably) you're using to track calls.

The way I've addressed this is to name the mock and reference it directly, so that TypeScript and jest can agree on the mock's type.

In your example, where we are spying on an existing method, we name the spy:

const instance = new MyClass();
const logSpy = jest.spyOn(object, methodName);
expect(logSpy).toHaveBeenCalled();

In cases where we are constructing a complex mock, we build the mock out of other named mocks:

const sendMock = jest.fn()
jest.mock('electron', () => ({
  ipcRenderer: {
    send: sendMock,
  },
}));
// ...
expect(sendMock).toHaveBeenCalledTimes(1);
Blaisdell answered 20/11, 2020 at 23:28 Comment(0)
C
3

You have to disable @typescript-eslint/unbound-method and enable jest/unbound-method rule. The latter extends the first one, so you still need to depend on @typescript/eslint.

'@typescript-eslint/unbound-method': 'off',
'jest/unbound-method': 'error',
Californium answered 14/12, 2021 at 14:19 Comment(1)
Nailed it, thanks so much!Ongun
N
0

I'm also having this problem (jest vs. typescript-eslint). This is the eslint rule in question.

I tried a number of solutions (all around binding the mock function) and whilst I am still open to finding an elegant way to silence the linting rule without making my tests significantly less readable, I decided to disable the rule for my tests.

In my case I am mocking the electron ipcRenderer functions:

import { ipcRenderer } from 'electron';

jest.mock('electron', () => ({
  ipcRenderer: {
    once: jest.fn(),
    send: jest.fn(),
    removeAllListeners: jest.fn(),
  },
}));

Then in a test, expecting a call to the send mock:

expect(ipcRenderer.send).toHaveBeenCalledTimes(1);

Binding the function directly, e.g.

expect(ipcRenderer.send.bind(ipcRenderer)).toHaveBeenCalledTimes(1);

...passes the eslint rule but jest doesn't like it:

expect(received).toHaveBeenCalledTimes(expected)

Matcher error: received value must be a mock or spy function

Received has type:  function
Received has value: [Function bound mockConstructor]
Nebula answered 28/7, 2020 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.