【问题标题】:Jest mocking TypeScript class "No overload expects 1 type arguments"笑话 TypeScript 类“没有重载需要 1 个类型参数”
【发布时间】:2019-07-23 06:45:49
【问题描述】:

我正在尝试使用 Jest 模拟 TypeScript 类,我显然正在做某事,因为收到以下错误:

error TS2743: No overload expects 1 type arguments, but overloads do exist that expect either 0 or 2 type arguments.

这是我的代码:

Foo.ts

export default class Foo {
  bar(): number {
    return Math.random()
  }
}

Foo.test.ts

import Foo from './Foo'

describe('Foo', () => {
  it("should pass", () => {
    const MockFoo = jest.fn<Foo>(() => ({
      bar: jest.fn(() => {
        return 123
      }),
    }))
  })
})

完整的错误:

TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
src/Foo.test.ts:6:29 - error TS2743: No overload expects 1 type arguments, but overloads do exist that expect either 0 or 2 type arguments.

6     const MockFoo = jest.fn<Foo>(() => ({
                              ~~~

更新

如果有任何相关性,这是我的 Jest 配置:

module.exports = {
  moduleFileExtensions: ['ts', 'js'],
  transform: {
    '^.+\\.ts$': 'ts-jest',
  },
  testMatch: ['**/src/**/*.test.(ts)'],
  testEnvironment: 'node',
};

【问题讨论】:

    标签: typescript mocking jestjs


    【解决方案1】:

    事实证明,通过关闭诊断 [1],可以让 TypeScript 编译器忽略此类错误。

    // jest.config.js
    module.exports = {
      // [...]
      globals: {
        'ts-jest': {
          diagnostics: false
        }
      }
    };
    

    但是,我目前还不清楚这可能会产生什么其他影响。

    [1]https://huafu.github.io/ts-jest/user/config/diagnostics#enabling-diagnostics-for-test-files-only

    【讨论】:

      【解决方案2】:

      Jest 具有以下 jest.fn 的签名:

      /**
       * Creates a mock function. Optionally takes a mock implementation.
       */
      function fn<T, Y extends any[]>(implementation?: (...args: Y) => T): Mock<T, Y>;
      

      因此,您需要为 args 指定类型数组,在您的特定情况下,您可以只传递一个空数组,因为您的实现函数中没有 args。

      const MockFoo = jest.fn<Foo, []>(() => ({
      

      【讨论】:

        【解决方案3】:

        你可以使用ts-jestmocked()函数:

        这是所有类型安全的,并且在 TypeScript 中编译时不会出现警告:

        import Foo from './Foo'
        import {mocked} from 'ts-jest/utils'
        
        function argIsFoo(foo : Foo) {
            ; // do nothing
        }
        
        describe('Foo', () => {
            it("should pass", () => {
                const mockFoo = mocked({
                    bar: jest.fn(() => {
                        return 123
                    })
                });
        
                // mockFoo is compatible with Foo class
                argIsFoo(mockFoo);
        
                // method has the right type
                expect(mockFoo.bar()).toEqual(123);
        
                // can use the mock in expectations
                expect(mockFoo.bar).toHaveBeenCalled();
        
                // is type safe access method as a mock
                expect(mockFoo.bar.mock.calls.length).toEqual(1);
            });
        });
        

        如果你只想模拟出 Foo 的一些方法,那么在mocked() 中你需要用as unknown as Foo 强制转换你的模拟对象

        import {mocked} from 'ts-jest/utils'
        
        class Foo {
            bar(): number {
                return Math.random();
            }
            dontMockMe(): string {
                return "buzz";
            }
        }
        
        function argIsFoo(foo : Foo) {
            ; // do nothing
        }
        
        describe('Foo', () => {
            it("should pass", () => {
                const mockFoo = mocked({
                    bar: jest.fn(() => {
                        return 123
                    })
                } as unknown as Foo);
        
                // mockFoo is compatible with Foo class
                argIsFoo(mockFoo);
        
                // method has the right type
                expect(mockFoo.bar()).toEqual(123);
        
                // can use the mock in expectations
                expect(mockFoo.bar).toHaveBeenCalled();
        
                // is type safe access method as a mock
                expect(mockFoo.bar.mock.calls.length).toEqual(1);
            });
        });
        

        【讨论】:

          猜你喜欢
          • 2021-10-24
          • 1970-01-01
          • 1970-01-01
          • 2012-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-14
          相关资源
          最近更新 更多