typescriptunit-testingjestjsnestjs

How to mock optional methods as undefined in Jest?


I am writing unit tests for a NestJS/Express server that uses the express-session package. It has an object with methods that might not always be defined. In my code I check for it to exist first, like this:

clearAllSessions(): Promise<string> {
  return new Promise<string>((resolve, reject) => {
   if (this.sessionStore.clear != null) {
      this.sessionStore.clear();
      resolve(`The sessions have been cleared!`);
    } else {
      reject(new Error(`Unable to clear sessions!`));
    }
  });
}

And I am writing a test like this (which uses a helper method to get errors, not relevant here)

it('should throw an error when session clear is not available to be called', async () => {
  jest.spyOn(sessionStore, 'clear').mockImplementation(undefined)

  const result = await getError(() => adminSvc.clearAllSessions());

  expect(sessionStore.clear).not.toHaveBeenCalled();
  expect(result).toEqual(new Error(`Unable to clear sessions!`));
});

The problem is that this.sessionStore.clear will return a jest mock function and not just plain undefined like my code would check for, so the test takes that first code branch which is not what I want. How to I just mock the implementation to be nothing?


Solution

  • Just use Object.defineProperty() to modifiy an existing property on an object.

    const sessionStore: { clear?: () => void } = {
      clear() {
        console.log('real implementation');
      },
    };
    
    describe('78741514', () => {
      test('should pass', () => {
        const restore = sessionStore.clear;
        Object.defineProperty(sessionStore, 'clear', { value: undefined });
        expect(sessionStore.clear).toBeUndefined();
        sessionStore.clear = restore;
      });
    });