使用 Jest 测试 TypeScript:“没有重载与此调用匹配”

Cer*_*ean 10 unit-testing typescript apollo jestjs apollo-server

我正在使用 Jest 测试 Apollo 服务器RESTDataSource。我的应用程序是用 TypeScript 编写的。我的类CDCDataSource扩展了抽象类RESTDataSource,它本身扩展了抽象类DataSource。 具有允许您从外部 REST 数据源提取数据的RESTDataSource方法。get我希望模拟这个方法,因为我希望模拟外部数据源。

  protected async get<TResult = any>(
    path: string,
    params?: URLSearchParamsInit,
    init?: RequestInit,
  ): Promise<TResult> {
    return this.fetch<TResult>(
      Object.assign({ method: 'GET', path, params }, init),
    );
  }
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试使用 Jest 来模拟这个方法时spyOn——遵循这里的第二个答案:Jest:如何模拟类的一个特定方法——

import CDCDataSource from '../CDCDataSource';

test('Test', () => {
    let dataSource = new CDCDataSource();
    let spy = jest.spyOn(dataSource, 'get').mockImplementation(() => 'Hello');
    expect(dataSource.get()).toBe('Hello');


Run Code Online (Sandbox Code Playgroud)

但是,我收到 TypeScript 错误

TS2768:没有重载与此调用匹配

越过get在jest.spyOn(dataSource,'get')

我得到

在此输入图像描述

越过get在

expect(dataSource.get()).toBe('Hello');

所以看来问题的一部分在于这是一个保护方法——我不清楚如何测试这个方法以便能够模拟 API。

我的tsconfig.json是

{
  "compilerOptions": {
    "target": "ES6",
    "lib": [
      "esnext",
      "dom"
    ],
    "skipLibCheck": true,
    "outDir": "dist",
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "sourceMap": true,
    "alwaysStrict": true,
  },
  "exclude": [
    "node_modules"
  ]
}
Run Code Online (Sandbox Code Playgroud)

这是一个 Node Apollo 服务器项目(使用 Node 12.14.0 和 TypeScript 3.8.3)

感谢您提供任何线索!

Iva*_* V. 13

您正在尝试访问一个protected方法。

如果您不想或无法重新架构您的类,您可以使用ts-ignore来抑制错误。

    // @ts-ignore`
    let spy = jest.spyOn(dataSource, 'get').mockImplementation(() => 'Hello');
Run Code Online (Sandbox Code Playgroud)

或者,您可以扩展原始类,使用仅用于测试的类,该类将具有仅代理受保护方法的公共方法。

test('Protected method',()=>{

  class Test extends OriginalClass {
    testProtected(){
      super.protectedMethod()
    }
  }
  let dataSource = new Test();
  let spy = jest.spyOn(dataSource, 'testProtected').mockImplementation(() => 'Hello');
})
Run Code Online (Sandbox Code Playgroud)

  • 当您编写测试时,最好使用“@ts-expect-error” (3认同)