如何使用 jest 框架仅模拟模块中的一个 TypeScript 类,但保留其他类/函数不变

问题描述 投票:0回答:2

我有一个打字稿模块,其中包含我正在尝试用玩笑测试的功能。我尝试测试的函数使用与该函数在同一模块中定义的打字稿类。两者均已出口。

我正在尝试模拟该类,但模拟的类没有被使用。正在使用被测文件中的原始版本。

免责声明:这是为了简洁起见而设计的示例,但与我正在使用的代码库的设计方式非常相似。

这是代码:

// 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');
   });
});

我的测试输出是:

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 |

显然,我没有正确设置我的模拟,但是笑话文档似乎很简单地说明了如何在打字稿中执行此操作和/或如何处理单个模块导出多个函数/类而您不导出的情况想要嘲笑一切。

typescript unit-testing jestjs mocking
2个回答
0
投票

经过一番惊愕之后,事实证明这是不可能实现的。更准确地说,在我的示例中,尽管 Foo 在我的测试脚本上下文中被模拟,但 fubar 看到的 Foo 副本是未模拟的版本。唯一的解决方案是将 Foo 移动到不同的模块/文件。


0
投票

这对我有用:

import MyClass from "mymodule";

const myMockObject = {
  myFunction: jest.fn()
}
jest.mock("mymodule", () => {
  const originalModule = jest.requireActual("mymodule");

  //Mock the default export and named export 'foo'
  return {
    __esModule: true,
    ...(originalModule as any),
    MyClass: jest.fn().mockImplementation(() => {
      return myMockObject;
    }),
  };
});
© www.soinside.com 2019 - 2024. All rights reserved.