3
votes

Jest moqueur de la classe TypeScript "Aucune surcharge n'attend 1 arguments de type"

J'essaie de me moquer d'une classe TypeScript avec Jest et je fais évidemment quelque chose car je reçois l'erreur suivante:

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

Voici mon code:

Foo.ts

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>(() => ({
                              ~~~

Foo.test.ts

import Foo from './Foo'

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

L'erreur complète:

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

Si cela est pertinent, voici ma configuration Jest:

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

p >


0 commentaires

3 Réponses :


1
votes

En fait, il est possible que le compilateur TypeScript ignore des erreurs comme celle-ci en désactivant les diagnostics [1].

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

Cependant, je ne sais actuellement pas quelles autres implications cela pourrait ont.

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


0 commentaires

6
votes

Jest a la signature suivante pour jest.fn:

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

Vous devez donc spécifier le tableau de types pour les args, dans votre cas particulier, vous pouvez simplement passer un tableau vide comme là il n'y a pas d'arguments dans votre fonction d'implémentation.

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


0 commentaires

1
votes

Vous pouvez utiliser le ts-jest mocked () fonction:

Tout est sûr et compile sans avertissement dans TypeScript:

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

Si vous voulez seulement vous moquer de certaines méthodes de Foo , puis dans mocked () vous devez lancer votre objet fictif avec aussi inconnu que Foo :

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


0 commentaires