Jest-Reaktionstest: Überprüfen Sie den Status nach der Verzögerung

Lesezeit: 4 Minuten

Benutzeravatar von Jack M
Jack M.

Ich bin wirklich verwirrt, wenn ich versuche, mithilfe der Jest-Dokumentation einen Test zu erstellen https://facebook.github.io/jest/docs/timer-mocks.html#content

Ich versuche, einen Status zu überprüfen, wenn der Container bereitgestellt wird, und einige Sekunden später, nachdem ich manuell Werte im Status festgelegt habe (mit setTimeout()).

Ich habe eine Funktion in mains „componentDidMount“ wie diese:

componentDidMount() {
    this.setStateAfterDelay();
}

Und was die Funktion macht, ist:

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

Ich habe den ersten Teil erreicht mit:

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

Aber ich habe keine Ahnung, wie ich den Status nach, sagen wir, 2000 ms noch einmal überprüfen soll?

Jede Hilfe ist willkommen 🙂

Benutzer-Avatar von Lukas Liesis
Lukas Liesis

Während Jest problemlos asynchronen Code ausführen kann, können Sie die Kombination von Promise und SetTimeout verwenden, um etwas zu warten. Dieser Code wartet beispielsweise 2 Sekunden:

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

Vollständiger Beispieltest. Vergessen Sie nicht hinzuzufügen async Flag vor der Callback-Funktion:

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

Beachten Sie außerdem, dass das standardmäßige „Timeout“ 5 Sekunden (5000 ms) beträgt. Wenn Ihr Test möglicherweise länger dauert, können Sie hinzufügen jest.setTimeout(30000); über test(). 30000 stellt sicher, dass es 30 Sekunden lang nicht zu einer Zeitüberschreitung kommt. Sie können eine beliebige Nummer hinzufügen, die Sie benötigen. Vollständiges Beispiel mit setTimeout:

jest.setTimeout(30000);

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

Sie können Timeout auch in der Jest-Konfiguration hinzufügen. Hier sind Konfigurationsdokumente

  • Was ist der Unterschied zu FakeTimers?

    – aProgger

    1. Dezember 2021 um 15:54 Uhr

  • FakeTimer sind, wie der Name schon sagt, Fake-Timer. setTimeout wartet auf echte Sekunden. Lesen Sie die Dokumente hier: jestjs.io/docs/timer-mocks

    – Lukas Liesis

    2. Dezember 2021 um 10:42 Uhr


  • Ich habe diesen Ansatz mit der React-Komponente verfolgt useState. Die Testbibliothek hat mich vor der Verwendung gewarnt act(...) und ich tat let timeout = null; await act(async () => { await new Promise((r) => { timeout = setTimeout(r, 2000) }) });. Dann muss ich es verwenden useEffect(()=> { return () => { cleanTimeout(timeout) } }, [timeout]) um alle Warnungen zu lösen.

    – Enrique René

    7. April 2022 um 19:33 Uhr


Ich habe diesen Code nicht wirklich getestet. Aber etwas Ähnliches sollte meiner Meinung nach funktionieren.

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

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

  • Ja, das scheint gut zu funktionieren! Ich dachte, dass es eine verrückte Syntax mit Unit-Tests gibt, um dies zu erreichen. Danke!

    – Jack M.

    3. August 2017 um 9:10 Uhr

  • Läuft das wirklich? Ich sehe hier keinen Debug-Zeiger, aber mein Testfall wird grün.

    – Tukaram Bhosale

    16. März 2021 um 17:46 Uhr

  • Das scheint nicht zu funktionieren. Wo montieren Sie?

    – png

    6. August 2021 um 17:06 Uhr

  • Aufgrund von setTimeout wird dieser Test nicht ausgeführt, schlägt aber auch nicht fehl und Sie sehen Grün in der Testabdeckung

    – Rohit Singh

    28. März 2022 um 21:16 Uhr

Sie müssen Ihre Tests nicht verzögern, sondern rufen einfach an jest.runAllTimers() vor der Behauptung, wird funktionieren.

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

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

Sie können auch anrufen useFakeTimers() in einem beforeEach wenn Sie mehrmals testen möchten und auch runAllTimers() könnte in einem anderen sein beforeEach damit du dich nicht wiederholst.

Ich weiß, dass dies eine Frage ist, wie man etwas nach 20 Sekunden überprüft. Dies könnte aber auch ein Indikator dafür sein, dass Sie nicht 20 Sekunden lang testen möchten, da es manchmal darauf ankommt, ob eine bestimmte Aktion mit den richtigen Eingaben ausgeführt wurde. In diesem Fall könnten Sie Ihren Code etwas umstrukturieren, sodass Sie eine Dispatch-Funktion übergeben können. Zum Beispiel

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

Weil dispatch übergeben wird, daher können Sie Folgendes problemlos im Testcode verwenden.

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

Natürlich geht man davon aus, dass es Ihnen egal ist, ob es 20 Sekunden sind, sondern dass Sie sich mehr um den Workflow-Prozess kümmern.

1453830cookie-checkJest-Reaktionstest: Überprüfen Sie den Status nach der Verzögerung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy