Je travaille sur un projet React et j'utilise jest pour écrire des tests pour mon code.
Voici le code que je souhaite tester.
test('should call handleSuccess', () => {
signupAPI.mockImplementation((user) => Promise.resolve(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors);
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});
Voici le code du test:
const handleSubmit = (handleSuccess, handleErrors) => {
signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
Lorsque j'exécute le test, il ne passe jamais à la partie «alors» après la promesse. Comment tester que la fonction à l'intérieur de la partie then est réellement appelée?
3 Réponses :
Le problème avec handleSubmit est qu'il traite les promesses comme des rappels glorifiés. Il n'est pas nécessaire de transmettre des rappels à puis et catch . Cela ne renvoie pas de promesse, donc ne peut pas être enchaîné.
Voici comment cela pourrait être corrigé:
const handleSubmit = () => signupAPI(user)
et
test('should call handleSuccess', async () => {
...
handleSubmit(handleSuccess, handleErrors);
await handleSubmit(handleSuccess, handleErrors);
expect(signupAPI).toHaveBeenCalled();
expect(handleSuccess).toHaveBeenCalled();
});
Et voici comment cela pourrait être correctement écrit:
const handleSubmit = (handleSuccess, handleErrors) => {
return signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
Cette solution n'a pas toujours fonctionné pour moi sur certains cas particuliers
Si vous utilisez un retour dans handleSubmit cela fonctionnera. Essayez ceci:
return handleSubmit(handleSuccess, handleErrors).then(() => {
...
});
Et pour le test:
test('should call handleSuccess', () => {
signupAPI.mockImplementation((user) => Promise.resolve(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors).then(() => {
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});
});
Cela devrait très bien fonctionner! si cela ne fonctionne pas, vous pouvez essayer d'ajouter un retour à handleSubmit sur votre test comme
const handleSubmit = (handleSuccess, handleErrors) => {
return signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
Le problème est que vous n'attendez pas la promesse que vous créez dans le test:
test('should call handleSuccess', async() => {
const p = Promise.resolve()
signupAPI.mockImplementation((user) => p.then(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors);
await p
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});