Können Sie asynchrone Tests schreiben, die toThrow erwarten?

Lesezeit: 4 Minuten

Benutzer-Avatar
Sean

Ich schreibe einen asynchronen Test, der erwartet, dass die asynchrone Funktion so wirft:

it("expects to have failed", async () => {
  let getBadResults = async () => {
    await failingAsyncTest()
  }
  expect(await getBadResults()).toThrow()
})

Aber Scherz ist nur scheitern, anstatt die Prüfung zu bestehen:

 FAIL  src/failing-test.spec.js
  ● expects to have failed

    Failed: I should fail!

Wenn ich den Test umschreibe sieht das so aus:

expect(async () => {
  await failingAsyncTest()
}).toThrow()

Ich erhalte diesen Fehler anstelle eines bestandenen Tests:

expect(function).toThrow(undefined)

Expected the function to throw an error.
But it didn't throw anything.

Benutzer-Avatar
Lisandro

Sie können Ihre asynchrone Funktion wie folgt testen:

it('should test async errors', async () =>  {        
    await expect(failingAsyncTest())
    .rejects
    .toThrow('I should fail');
});

Die Zeichenfolge „Ich sollte scheitern“ stimmt mit jedem Teil des ausgegebenen Fehlers überein.

  • Dies ist nun dokumentiert in facebook.github.io/jest/docs/en/expect.html#rejects

    – 0x24a537r9

    19. Dezember 2017 um 22:02 Uhr

  • Hat tatsächlich Probleme, dokumentiertes Beispiel schlägt fehl. github.com/facebook/jest/issues/3601 hat Problemumgehungen einschließlich await expect(failingAsyncTest()).rejects.toHaveProperty('message', 'I should fail');

    – MrYellow

    6. April 2018 um 8:18 Uhr

  • @Lisandro Dieser Code funktioniert nicht. Ja, der Unit-Test besteht, aber nicht weil failingAsyncTest warf die richtige Art von Fehler. Es ist offensichtlicher, wenn Sie die Implementierung von ändern failingAsyncTest werfen der falsche Fehler statt dem richtigen. (unter Verwendung von Jest 23.6)

    – Tom

    15. Oktober 2018 um 18:39 Uhr


  • @Tom Die Lösung behauptet nie, mit dem Fehler übereinzustimmen Typ. Es gibt eindeutig an, dass die Zeichenfolge mit dem Fehler übereinstimmt Nachricht. Es funktioniert einwandfrei. Am besten.

    – Lisandro

    20. Oktober 2018 um 1:41 Uhr

  • Was ist der Unterschied zwischen Expect(Promise).Rejects.ToMatch(Error) und Expect(Promise).Rejects.ToThrow(Error). Sollten Ablehnungen nicht den eigentlichen Fehler auspacken? Dann würde dies keinen Sinn ergeben (oder ergibt für mich keinen Sinn) -> Expect(error).toThrow(error). Hier ein Beispiel für toMatch mit Rejects: jestjs.io/docs/asynchronous#asyncawait

    – Benutzer3245268

    28. Juni 2021 um 7:44 Uhr


Ich möchte dem nur hinzufügen und sagen, dass die Funktion, die Sie testen, ein tatsächliches Error-Objekt werfen muss throw new Error(...). Jest scheint nicht zu erkennen, wenn Sie nur einen Ausdruck wie werfen throw 'An error occurred!'.

  • Nun, Sie haben mir gerade eine Schiffsladung Zeit gespart.

    – Nick

    4. Januar 2021 um 15:53 ​​Uhr

  • Gibt es eine Problemumgehung, wenn wir behalten sollen throw 'an error'?

    – Mikey

    25. März 2021 um 0:25 Uhr

  • Ich verpacke die Funktion, die einen Try-Catch in die Tests einwerfen soll. Und dann im Fangblock kann ich tun expect(error).toMatchObject(expectedError) sieht aber ziemlich drollig aus

    – Mikey

    25. März 2021 um 0:32 Uhr

  • Anscheinend funktioniert dies auch nicht mit benutzerdefinierten Fehlern, die von Error erben 🙁

    – Deckel

    24. Februar um 11:29 Uhr

await expect(async () => { 
    await someAsyncFunction(someParams); 
}).rejects.toThrowError("Some error message");

Wir müssen den Code in eine Funktion packen, um den Fehler abzufangen. Hier erwarten wir, dass die von someAsyncFunction ausgegebene Fehlermeldung gleich „Some error message“ sein sollte. Wir können auch den Ausnahmehandler aufrufen

await expect(async () => { 
    await someAsyncFunction(someParams); 
}).rejects.toThrowError(new InvalidArgumentError("Some error message"));

Weiterlesen https://jestjs.io/docs/expect#tothrowerror

Benutzer-Avatar
Laode Muhammed Al Fatih

Benutzerdefinierte Fehlerklasse

Die Verwendung von rejects.toThrow wird bei dir nicht funktionieren. Stattdessen können Sie die kombinieren rejects Methode mit der toBeInstanceOf Matcher, um den ausgegebenen benutzerdefinierten Fehler abzugleichen.

Beispiel

it("should test async errors", async () => {
  await expect(asyncFunctionWithCustomError()).rejects.toBeInstanceOf(
    CustomError
  )
})

oder


it("should test async errors", async () => {
  await expect(async () => {
    await asyncFunctionWithCustomError()
  }).rejects.toBeInstanceOf(CustomError)
})

Um viele Testbedingungen machen zu können, ohne jedes Mal das Promise auflösen zu müssen, geht auch das:

it('throws an error when it is not possible to create an user', async () => {
        const throwingFunction = () => createUser(createUserPayload)

        // This is what prevents the test to succeed when the promise is resolved and not rejected
        expect.assertions(3)

        await throwingFunction().catch(error => {
            expect(error).toBeInstanceOf(Error)
            expect(error.message).toMatch(new RegExp('Could not create user'))
            expect(error).toMatchObject({
                details: new RegExp('Invalid payload provided'),
            })
        })
    })

Benutzer-Avatar
Tomerikoo

Ich habe Firebase-Cloud-Funktionen getestet und folgendes herausgefunden:

test("It should test async on failing cloud functions calls", async () => {
    await expect(async ()=> {
        await failingCloudFunction(params)
    })
    .rejects
    .toThrow("Invalid type"); // This is the value for my specific error
  });

Dies baut auf Lisandros Antwort auf.

Benutzer-Avatar
Günter Zöchbauer

Das hat bei mir funktioniert

it("expects to have failed", async () => {
  let getBadResults = async () => {
    await failingAsyncTest()
  }
  expect(getBadResults()).reject.toMatch('foo')
  // or in my case
  expect(getBadResults()).reject.toMatchObject({ message: 'foo' })
})

1018250cookie-checkKönnen Sie asynchrone Tests schreiben, die toThrow erwarten?

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

Privacy policy