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 });