web-dev-qa-db-fra.com

Test des exceptions dans les méthodes asynchrones

Je suis un peu coincé avec ce code (c'est un exemple):

public async Task Fail()
{
    await Task.Run(() => { throw new Exception(); });
}

[Test]
public async Task TestFail()
{
    Action a = async () => { await Fail(); };
    a.ShouldThrow<Exception>();
}

Le code n'intercepte pas l'exception et échoue avec

Une exception System.Exception attendue, mais aucune exception n'a été levée.

Je suis sûr que je manque quelque chose, mais les médecins semblent suggérer que c'est la voie à suivre. Une aide serait appréciée.

49
user227895

Tu devrais utiliser Func<Task> au lieu de Action:

[Test]
public void TestFail()
{
    Func<Task> f = async () => { await Fail(); };
    f.ShouldThrow<Exception>();            
}

Cela appellera l'extension suivante utilisée pour vérifier les méthodes asynchrones

public static ExceptionAssertions<TException> ShouldThrow<TException>(
    this Func<Task> asyncAction, string because = "", params object[] becauseArgs)
        where TException : Exception        

En interne, cette méthode exécutera la tâche renvoyée par Func et l'attendra. Quelque chose comme

try
{
    Task.Run(asyncAction).Wait();
}
catch (Exception exception)
{
    // get actual exception if it wrapped in AggregateException
}

Notez que le test lui-même est synchrone.

80
Sergey Berezovskiy

Avec Fluent Assertions v5 +, le code sera le suivant:

ISubject sut = BuildSut();
//Act and Assert
Func<Task> sutMethod = async () => { await sut.SutMethod("whatEverArgument"); };
await sutMethod.Should().ThrowAsync<Exception>();

Cela devrait marcher.

12
gatsby