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 }
3 Réponses :
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.
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' }))
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
a > pour vous assurer que le test échoue si la Promesse
se résout)
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