Je reçois toujours un Warning: An update to App inside a test was not wrapped in act(...). dans ma suite de tests chaque fois que je fais une requête API et que je mets à jour l'état.
J'utilise la bibliothèque react-testing. J'ai également essayé d'utiliser les utils de test ReactDOM, j'ai obtenu le même résultat. Une autre chose que j'ai essayée a été de mettre le conteneur en act , j'ai toujours obtenu le même résultat.
Veuillez noter que: Mon application fonctionne et mon test réussit. J'ai juste besoin de savoir ce que je faisais de mal ou si c'est un bogue dans le paquet react-dom qui fait apparaître cette erreur. Et il est mauvais de se moquer de l'erreur de la console et de la désactiver.
const [data, setData] = useState([]);
const [error, setError] = useState('');
const fetchInitData = async () => {
try {
const res = await fetch(API_URL);
const data = await res.json();
if (data.fault) {
setError('Rate limit Exceeded');
} else {
setData(data.results);
}
} catch(e) {
setError(e.message);
}
};
useEffect(() => {
fetchInitData();
}, [isEqual(data)]);
Voici l'implémentation du hook:
global.fetch = require('jest-fetch-mock');
it('should clear select content item', async () => {
fetch.mockResponseOnce(JSON.stringify({ results: data }));
const { container } = render(<App />);
const content = container.querySelector('.content');
await wait();
expect(content.querySelectorAll('.content--item').length).toBe(2);
});
4 Réponses :
C'est un problème connu, vérifiez ce problème dans Github https://github.com/kentcdodds/react-testing-library/issues/281
Pour vous débarrasser de l'avertissement act() vous devez vous assurer que vos promesses se résolvent de manière synchrone. Vous pouvez lire ici comment procéder.
Sommaire:
La solution à cela est un peu compliquée:
- nous polyfill Promise globalement avec une mise en œuvre qui peut résoudre les promesses `` immédiatement '', comme la promesse
- transpilez votre javascript avec une configuration babel personnalisée comme celle de ce dépôt
- utilisez jest.runAllTimers (); cela va également vider la file d'attente des tâches de promesse
J'ai eu ce problème et j'ai renoncé à utiliser wait and async à la place, j'ai utilisé des faketimers de plaisanterie et ainsi de suite, donc votre code devrait être quelque chose comme ça.
global.fetch = require('jest-fetch-mock');
it('should clear select content item', /*async */ () => {
jest.useFakeTimers();
fetch.mockResponseOnce(JSON.stringify({ results: data }));
const { container } = render(<App />);
const content = container.querySelector('.content');
// await wait();
act(() => {
jest.runAllTimers();
});
expect(content.querySelectorAll('.content--item').length).toBe(2);
});Pour tous ceux qui tombent dessus plus d'un an plus tard comme je l'ai fait, le problème mentionné par Giorgio a depuis été résolu, et wait a depuis été remplacé par waitFor , comme documenté ici:
https://testing-library.com/docs/dom-testing-library/api-async/
Cela étant le cas, je pense que la solution à l'avertissement devrait maintenant être quelque chose comme ceci:
beforeEach(async () => {
await waitFor(() => render(<App />));
});
Dans mon cas, j'avais un composant App chargeant des données de manière asynchrone dans un hook useEffect , et je useEffect donc cet avertissement à chaque test, en utilisant beforeEach pour rendre App . C'était la solution spécifique pour mon cas:
import { render, waitFor } from '@testing-library/react';
// ...
it('should clear select content item', async () => {
fetch.mockResponseOnce(JSON.stringify({ results: data }));
const { container } = render(<App />);
const content = container.querySelector('.content');
await waitFor(() =>
expect(content.querySelectorAll('.content--item').length).toBe(2);
);
});
Tout cela fait-il partie d'une fonction?
Ouais c'est ça. Laisse-moi ajouter que ça marche et que mon test réussit. Le seul problème, ce sont les erreurs ennuyeuses