javascript - Hvordan sjekke flere argumenter på flere kall for jest spioner?
Jeg har følgende funksjon i en React-komponent:
onUploadStart(file, xhr, formData) {
formData.append('filename', file.name);
formData.append('mimeType', file.type);
}
Dette er testen min som i det minste får spionen til å bli kalt:
const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);
expect(formData.append).toHaveBeenCalledWith(
['mimeType', 'someMimeType'],
['fileName', 'someFileName']
);
Imidlertid fungerer ikke påstanden:
Expected mock function to have been called with:
[["mimeType", "someMimeType"], ["fileName", "someFileName"]]
But it was called with:
["mimeType", "someMimeType"], ["filename", "someFileName"]
Hva er riktig måte å bruke toHaveBeenCalledWith på?
Svar #1
Jeg kunne mocke flere kall og sjekke argumentene på denne måten:
expect(mockFn.mock.calls).toEqual([
[arg1, arg2, ...], // First call
[arg1, arg2, ...] // Second call
]);
hvor mockFn er navnet på din mockede funksjon.
Svar #2
Siden jest 23.0 finnes det .toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....) https://jestjs.io/docs/expect#tohavebeennthcalledwithnthcall-arg1-arg2-
Også under aliaset: .nthCalledWith(nthCall, arg1, arg2, ...)
Hvis du har en mock-funksjon, kan du bruke
.toHaveBeenNthCalledWithfor å teste hvilke argumenter den ble kalt med som nr. n. For eksempel, la oss si at du har endrinkEach(drink, Array<flavor>)-funksjon som brukerfpå en rekke smaker, og du vil forsikre deg om at når du kaller den, er den første smaken den opererer på'lemon'og den andre'octopus'. Du kan skrive:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenNthCalledWith(1, 'lemon');
expect(drink).toHaveBeenNthCalledWith(2, 'octopus');
});
Merk: det n-te argumentet må være et positivt heltall som starter fra 1.
Svar #3
Du kan også teste toHaveBeenCalledWith og teste flere ganger for hver forventet parameterkombinasjon.
Et eksempel er at Google Analytics-plugin API bruker det samme funksjonskallet med forskjellige parameterkombinasjoner.
function requireGoogleAnalyticsPlugins() {
...
ga('create', 'UA-XXXXX-Y', 'auto');
ga('require', 'localHitSender', {path: '/log', debug: true});
ga('send', 'pageview');
}
For å teste dette sjekker eksemplet nedenfor at ga har blitt kalt tre ganger med de ulike parameterkombinasjonene.
describe("requireGoogleAnalyticsPlugins", () => {
it("requires plugins", () => {
requireGoogleAnalyticsPlugins();
expect(GoogleAnalytics.ga.toHaveBeenCalledTimes(3);
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('create', 'UA-XXXXX-Y', 'auto');
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('require', 'localHitSender', {path: '/log', debug: true});
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('send', 'pageview');
});
});
I OP-tilfelle kunne du teste dette med
expect(formData.append).toHaveBeenCalledWith('mimeType', 'someMimeType');
expect(formData.append).toHaveBeenCalledWith('fileName', 'someFileName');
Svar #4
Signaturen er .toHaveBeenCalledWith(arg1, arg2, ...), hvor arg1, arg2, ... betyr i en enkel kall (se).
Hvis du vil teste flere kall, bare forvent det flere ganger.
Dessverre har jeg ennå ikke funnet en metode for å teste rekkefølgen på flere kall.
Svar #5
Du kan også opprette et array med de forventede argumentene per kall og løpe gjennom det:
const expectedArgs = ['a', 'b', 'c', 'd']
expectedArgs.forEach((arg, index) =>
expect(myFunc).toHaveBeenNthCalledWith(index + 1, arg))
Denne løsningen tar hensyn til rekkefølgen på kallene. Hvis du ikke bryr deg om rekkefølgen, kan du bruke toHaveBeenCalledWith uten indeks i stedet.
