web-dev-qa-db-fra.com

Pourquoi les tests unitaires "async void" ne peuvent-ils pas être reconnus?

async void les tests unitaires ne peuvent pas être exécutés dans Visual Studio 2012:

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async void InvisibleMyTestMethod()
    {
        await Task.Delay(1000);
        Assert.IsTrue(true);
    }
}

Si je veux avoir un test unitaire asynchrone, la méthode de test doit renvoyer une tâche:

[TestMethod]
public async Task VisibleMyTestMethod()
{
    await Task.Delay(1000);
    Assert.IsTrue(true);
}

Pourquoi en est-il ainsi? Non pas que je doive absolument avoir un async void méthode de test, je suis juste curieux. Visual Studio 2012 ne donne aucun avertissement ni erreur lorsque vous créez un async void méthode de test même si elle ne pourra pas être exécutée ...

74
Max

async void les méthodes doivent être considérées comme "Fire and Forget" - il n'y a aucun moyen d'attendre qu'elles se terminent. Si Visual Studio devait démarrer l'un de ces tests, il ne pourrait pas attendre la fin du test (le marquer comme réussi) ou intercepter toutes les exceptions levées.

Avec un async Task, l'appelant peut attendre la fin de l'exécution et intercepter toutes les exceptions levées lors de son exécution.

Voir cette réponse pour plus de discussion sur async void contre async Task.

77
Richard

C'est simplement parce que MSTest ne prend pas en charge async void tests unitaires. Il est possible de le faire en introduisant un contexte dans lequel ils peuvent s'exécuter.

MSTest ne prend pas en charge cela, probablement parce que Microsoft a décidé qu'il s'agissait d'un changement trop important pour les tests existants (il est possible que les tests existants se bloquent s'ils recevaient un contexte inattendu).

Il n'y a pas d'avertissement/d'erreur du compilateur car c'est un code C # parfaitement valide. La seule raison pour laquelle cela ne fonctionne pas est à cause du cadre de test unitaire (c'est-à-dire que je crois que xUnit prend en charge async void tests), et ce serait une violation flagrante de la séparation des préoccupations que le compilateur C # examine vos attributs, détermine que vous utilisez MSTest et décide que vous ne vouliez vraiment pas utiliser async void.

21
Stephen Cleary

J'ai trouvé dans VS2015 que toutes les méthodes de test décorées avec async ne s'afficheraient pas dans l'Explorateur de tests. J'ai fini par supprimer le mot clé async et remplacer l'appel en attente dans le test par une tâche.Attendre () et j'ai effectué mes assertions sur la tâche.Résultat.

Semble fonctionner correctement. Je ne l'ai pas encore essayé avec des tests d'exception.

var task = TheMethodIWantToTestAsync(someValue);
task.Wait();
var response = task.Result;

Assert.IsNotNull(response);
Assert.IsTrue(response.somevalue);
19
Nick Wright