typescript - Mocking av nestede funksjonskall i Jasmine


Jeg prøver for øyeblikket å teste TypeScript-funksjonene mine ved å bruke Jasmine:

//AB.ts

export async function A() {
}
export async function B() {
    A();
}

Jeg prøver å enhetsteste funksjonen B ved å mocke A. Jeg vil se om A blir kalt. Her er hva jeg har:

//AB.spec.ts
import * as AB from './AB'

describe('AB has a function B that ', () => {
    it('calls A', async () => {
        let ASpy: jasmine.Spy;
        ASpy = spyOn(AB, 'A').and.returnValue(Promise.resolve({}));
        await AB.B();
        expect(ASpy).toHaveBeenCalled();
    });
});

Når jeg kjører denne testen, får jeg beskjed om at ASpy aldri ble kalt. Men etter nærmere undersøkelse fant jeg at A-funksjonen definitivt ble kalt. Så det ser ut til at A-funksjonen ble kalt, men mocken jeg laget for funksjonen ble ikke utløst. Jeg har prøvd å implementere A-funksjonen i en annen fil og kalle den i B og mocke den i AB.spec.ts; i det scenarioet passerer testen, da expect bestemmer at ASpy ble kalt. Jeg er ikke sikker på hvorfor det å ha de to funksjonene i samme fil bryter testen, men å legge dem i separate filer gjør at testene passerer. Uansett, jeg håper å høre fra noen snart! Jeg har ikke noe imot å legge funksjonene i separate filer, men jeg vil unngå det så mye som mulig i fremtidige prosjekter.

Svar #1

Jeg ser at du bruker

Aspy = spyOn(AB,'A'); 

hvor AB ikke er et objekt av en komponent/klasse, men det er bare en konstant som du har brukt for å importere disse globale funksjonene til spesifikasjonsfilen din.

Så problemet ligger egentlig ikke i noen av kodene dine for å teste "async" funksjoner spesifikt, men det ligger i måten du lager spioner for funksjonene dine uten klasse-/komponentobjekter. Du bør kanskje sjekke denne tråden og endre din opprinnelige løsning for å se om det å gå tilbake til spionene dine ved å bruke en av løsningene i tråden nedenfor, gjør at de opprinnelige testene dine kjører fint.

Bruke Jasmine for å spionere på en funksjon uten et objekt

Svar #2

Jeg klarte å finne en måte å riktig mocke ut A inne i B. Trengte bare å legge til eksport-nøkkelordet til funksjonskallet mitt:

export async function B() {
    exports.A();
}

Dette gjør at omfanget til B kan se definisjonen av A, samtidig som .spec-filen kan se at A refererer til den eksporterte metoden til A.