Jest mocking TypeScript class “No overload expects 1 type arguments”

前端 未结 3 771
执笔经年
执笔经年 2020-12-18 11:45

I\'m trying to mock a TypeScript class with Jest and I\'m obviously doing something because receive the following error:

error TS2743: No overload expects 1          


        
相关标签:
3条回答
  • 2020-12-18 12:13

    Jest has the following signature for jest.fn:

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

    So you need to specify the array of types for the args, in your particular case you could just pass an empty array as there are no args in your implementation function.

    const MockFoo = jest.fn<Foo, []>(() => ({
    
    0 讨论(0)
  • 2020-12-18 12:16

    As it turns out, it's possible to have the TypeScript compiler ignore errors like this by turning off diagnostics [1].

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

    However, it's currently unclear to me what other implications this might have.

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

    0 讨论(0)
  • 2020-12-18 12:38

    You can use the ts-jest's mocked() function:

    This is all type safe and compiles without warnings in 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);
        });
    });
    

    If you only want to mock out some of Foo's methods, then in mocked() you need to cast your mock object with 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);
        });
    });
    
    0 讨论(0)
提交回复
热议问题