5
votes

Comment se moquer de la méthode const dans jest?

Je code de test unitaire en typographie, utilisez jest. Veuillez m'apprendre à simuler getData pour renvoyer la valeur attendue. Mon code comme ci-dessous:

// File util.ts
export const getData = async () => {
    // Todo something
    return data;
}

// File execution.ts import { getData } from './util';
function execute()
{
    // todo something
    const data = await getData();
    // todo something 
}


0 commentaires

3 Réponses :


0
votes

Essayez ce qui suit dans votre fichier de test. Importez la fonction depuis le module.

jest.mock('./util', () => ({ getData: jest.fn() }))
getData.mockReturnValue("abc");

Puis simulez le module avec la fonction et sa valeur de retour après toutes les instructions d'importation

 import { getData } from './util';

Puis utilisez-le dans vos tests.


0 commentaires

3
votes

Le problème est que votre fonction renvoie une promesse. En fonction de la façon dont vous l'utilisez, il existe plusieurs façons de se moquer de lui.

Le moyen le plus simple serait de se moquer directement, mais il retournera toujours la même valeur:

import {getData} from './util'
jest.mock('./util', () => ({ getData: ()=> jest.fn() }))

it('success case', async ()=>{
  const result = Promise.resolve('someValue')
  getData.mockImplementation(()=> result)

  // call your function to test
  await result // you need to use await to make jest aware of the promise

})

it('error case', async()=>{
  const result = Promise.reject(new Error('someError))
  getData.mockImplementation(()=> result)
  // call your function to test
  await expect(result).rejects.toThrow('someError');
})

Si vous souhaitez tester à la fois le cas résolu et le cas rejeté, vous devez vous moquer de getData afin qu'il renvoie un espion où vous pourrez plus tard modifier l'implémentation utilisez mockImplementation . Vous devez également utiliser async / await pour que le test fonctionne, jetez un œil à la docs sur les tests asynchrones:

// note, the path is relative to your test file
jest.mock('./util', () => ({ getData: ()=>'someValue' }))


1 commentaires

L'utilisation de .rejects est préférable pour tester le cas de rejet pour éviter les faux positifs du try / catch. (Au minimum, vous devez utiliser expect.assertions pour vous assurer que le test échoue si la Promesse se résout)



0
votes

Parce que les fonctions d'expression moqueuses peuvent être très difficiles à faire, je publie un exemple complet ci-dessous.

Scénario

Disons que nous voulons en tester code qui effectue un appel REST, mais nous ne voulons pas que l'appel REST réel soit effectué:

// mockAndSpyInternals.test.ts

import {doSomethingWithRest} from "./doWithApi";

afterEach(jest.clearAllMocks);   // Resets the spy between tests
jest.mock("./apiHelpers");       // Replaces runtime functions inside 'apiHelpers' with those found inside __mocks__. Path is relative to current file. Note that we reference the file we want to replace, not the mock we replace it with.

test("When doSomethingWithRest is called, a REST call is performed.", () => {

    // If we want to spy on the post method to perform assertions we must add the following lines. 
    // If no spy is wanted, these lines can be omitted. 
    const apiHelpers = require("./apiHelpers");
    const postSpy = jest.spyOn(apiHelpers, "post");

    // Alter the spy if desired (e.g by mocking a resolved promise)
    // postSpy.mockImplementation(() => Promise.resolve({..some object}))

    doSomethingWithRest();

    expect(postSpy).toBeCalledTimes(1)
    expect(postSpy).toHaveBeenCalledWith("some-url", 123);
});

Où le post est un expression de fonction dans un fichier séparé:

// __mocks__/apiHelpers.ts

export const post = jest.fn();

Configuration

Depuis le post code> est utilisé directement (et non passé en paramètre), nous devons créer un fichier fictif que Jest pourra utiliser lors des tests en remplacement de la vraie fonction post :

// apiHelpers.ts

export const post = (url: string, num: number) => {
    throw Error("I'm a REST call that should not run during unit tests!");
}

Espionner et tester

Maintenant, enfin dans le test réel, nous pouvons faire ce qui suit: p >

// doWithApi.ts

export const doSomethingWithRest = () => {
    post("some-url", 123);
}

Les exemples sont réalisés en utilisant Jest 24.9.0 et Typescript 3.7.4


0 commentaires