web-dev-qa-db-fra.com

Test de réactivité: vérifier l'état après un délai

Je suis vraiment confus d'essayer de créer un test à l'aide de la documentation Jest https://facebook.github.io/jest/docs/timer-mocks.html#content

J'essaie de vérifier un état lors du montage du conteneur, puis quelques secondes plus tard, après avoir défini manuellement les valeurs dans l'état (à l'aide de setTimeout ()).

J'ai une fonction dans le composantDidMount de Main comme ceci:

componentDidMount() {
    this.setStateAfterDelay();
}

Et ce que fait la fonction est:

setStateAfterDelay = () => {
    setTimeout(() => {
        this.setState({ fruits: ['banana', 'Apple', 'orange', 'vodka', 'kiwi'] });
    }, 1500);
}

J'ai réalisé la première partie avec:

const component = mount(<Main />);
expect(component.state().fruits).toEqual(null);

Mais je ne sais pas comment vérifier à nouveau l'état après, disons 2000 ms?

Toute aide est appréciée :)

13
Jack M.

Je n'ai pas vraiment testé ce code. Mais quelque chose de similaire devrait fonctionner, je pense.

const fruits = ['banana', 'Apple', 'orange', 'vodka', 'kiwi'];

it('mock setTimeout test', () => {
 jest.useFakeTimers();
 setTimeout(() => {
   expect(component.state().fruits).toEqual(fruits);
 }, 1500);
 jest.runAllTimers();
});
15
Dinesh Ramasamy

bien que jest puisse exécuter facilement du code asynchrone, vous pouvez utiliser la combinaison promise et setTimeout pour attendre un peu. Par exemple, ce code attendra 2 secondes:

await new Promise((r) => setTimeout(r, 2000));

Test d'échantillon complet. N'oubliez pas d'ajouter le drapeau async avant la fonction de rappel:

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

Gardez également à l'esprit que le "délai d'attente" par défaut est de 5 secondes (5000 ms). Si votre test peut durer plus longtemps, vous pouvez ajouter jest.setTimeout(30000); au-dessus de test(). 30000 s'assurera de ne pas expirer pendant 30 secondes. Vous pouvez ajouter n'importe quel numéro dont vous avez besoin. Exemple complet avec setTimeout:

jest.setTimeout(30000);

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});
6
Lukas

Vous n'avez pas besoin de retarder vos tests, il suffit d'appeler jest.runAllTimers() avant de confirmer, cela fonctionnera.

const fruits = ['banana', 'Apple', 'orange', 'vodka', 'kiwi'];

it('initializes the fruits state', () => {
 jest.useFakeTimers();
 jest.runAllTimers();
 expect(component.state().fruits).toEqual(fruits);
});

Vous pouvez également appeler useFakeTimers() dans un beforeEach si vous allez tester plusieurs fois et aussi runAllTimers() pourrait être à l'intérieur d'un autre beforeEach donc vous ne le faites pas ' t répétez-vous.

2
Warao

Je sais que c'est une question sur la façon de vérifier quelque chose après 20 secondes. Mais cela pourrait aussi être un indicateur que vous ne voulez pas tester 20 secondes, car ce qui est parfois important est de savoir si certaines actions ont été effectuées avec les bonnes entrées. Dans ce cas, vous pourriez restructurer un peu votre code afin de pouvoir passer une fonction de répartition. Par exemple

    function abc() {
        return dispatch => {
            return Promise.then(res => {})  // this would take 20 seconds
        }
    }

Étant donné que dispatch est transmis, vous pouvez donc facilement utiliser ce qui suit dans le code de test.

    const dispatch = Jest.fn()
    abc(dispatch)
    expect(dispatch).toBeCalled()

Bien sûr, l'hypothèse est que vous ne vous souciez pas si c'est 20 secondes, vous vous souciez plutôt du processus de workflow.

0
windmaomao