'How to mock only one typescript class from a module, but leave other classes/functions as is, using the jest framework

I have a typescript module with a function that I'm trying to test with jest. The function I'm trying to test uses a typescript class that's defined in the same module as the function. Both are exported.

I am trying to mock the class, but the mocked class isn't getting used. The original version in the file under test is being used.

Disclaimer: This is a contrived example for the sake of brevity, but is very similar to how the codebase is designed I'm working with.

Here's the code:

// mock.ts
export class Foo {
   bar(): string {
      return 'Original Foo.bar';
   }
}

export function fubar() {
   return new Foo().bar();
}

// mock.test.ts
import { expect, jest, test } from '@jest/globals';
import { fubar } from './mock';

jest.mock('./mock.ts', () => {
   return {
      ...(jest.requireActual('./mock') as Object),
      Foo: {
         bar: jest.fn().mockImplementation(() => {
            return 'Mocked Foo.bar';
         })
      }
   };
});

describe('Mock Testing', () => {
   test('Test if mocked Foo class works', () => {
      const result = fubar();
      expect(fubar()).toBe('Mocked Foo.bar');
   });
});

The output of my test is:

Expected: "Mocked Foo.bar"
Received: "Original Foo.bar"

      16 |    test('Test if mocked Foo class works', () => {
      17 |       const result = fubar();
    > 18 |       expect(fubar()).toBe('Mocked Foo.bar');
         |                       ^
      19 |    });
      20 | });
      21 |

Clearly, I'm not setting up my mock correctly, but the jest documentation seems to be light on how to do this in typescript and/or how to handle the case when a single module exports multiple functions/classes and you don't want to mock everything.



Solution 1:[1]

After much consternation, it turns out it is not possible to achieve this. More precisely, in my example, even though Foo is mocked in the context of my test script, the copy of Foo that fubar sees is the unmocked version. The only solution is to move Foo to a different module/file.

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 Tom Hoffman