73 votes

Tests pour les exceptions dans des 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'est pas intercepter l'exception, et ne parvient pas à

Prévu un Système.Exception levée, mais aucune anomalie n'a été jetés.

Je suis sûr que je suis absent quelque chose, mais les docs semblent suggérer c'est le chemin à parcourir. Un peu d'aide serait appréciée.

120voto

Sergey Berezovskiy Points 102044

Vous devez utiliser Func<Task> au lieu de Action:

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

Qui fera appel à la suite de l'extension qui est utilisé 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 sera exécuter la tâche retourné par Func et de l'attendre. 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.

27voto

gatsby Points 320

Avec Fluent Affirmations v5+ le code comme :

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

Cela devrait fonctionner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X