2
votes

Comment tester la partie alors après la promesse en plaisantant

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?


0 commentaires

3 Réponses :


2
votes

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


1 commentaires

Cette solution n'a pas toujours fonctionné pour moi sur certains cas particuliers



2
votes

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


0 commentaires

6
votes

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


0 commentaires