2017-06-29 3 views
2

Ich weiß, dass es eine schlechte Methode ist, eine Methode async void zurückgeben zu lassen, da es schwierig zu testen ist, aber gibt es einen Grund, dass ein Komponententest asynchrone Task statt async void zurückgeben muss?Ist es schlecht, Unit-Tests async void zurückgeben zu lassen?

Im Grunde ist dies ok:

[Test()] 
public async void MyTest() 
{ 
    //Some code to run test 
    //Assert Something 
} 

Oder sollte ich das tun:

[Test()] 
public async Task MyTest() 
{ 
    //Some code to run test 
    //Assert Something 
} 
+0

Möchten Sie wissen, ob Ihr Test endet, wann Ihr Test endet, und ob Ihr Test erfolgreich abgeschlossen wurde oder nicht? – Servy

+1

Die meisten Unit-Test-Runner unterstützen 'async void'-Methoden (durch Verwendung eines benutzerdefinierten Synchronisationskontexts). Dennoch ist es sicherer/sauberer, 'async Task' für Ihre Tests zu verwenden –

+1

@KevinGosse Es gibt noch viele Dinge, die Sie in Ihrer Methode tun können, um zu verhindern, dass das Testrahmenwerk auch mit einem benutzerdefinierten Sync-Kontext ordnungsgemäß funktioniert. (Zum Beispiel, einige Code mit 'ConfigureAwait (false);' ist alles was man braucht, um Dinge zu brechen.) – Servy

Antwort

2

zu zitieren Async/Await - Best Practices in Asynchronous Programming Von Stephen Cleary

Void-Rückgabe Asynchron-Methoden haben eine spezifische Zweck: asynchrone Event-Handler möglich zu machen. Es ist möglich, ein Ereignis Handler, der einige tatsächliche Art zurückgibt, aber das funktioniert nicht gut mit der Sprache; einen Ereignishandler aufzurufen, der einen Typ zurückgibt, ist sehr unpraktisch , und die Vorstellung eines Ereignishandlers, der tatsächlich etwas zurückgibt, macht nicht viel Sinn. Ereignisbehandlungsroutinen geben natürlich void zurück, sodass asynchrone Methoden void zurückgeben, sodass Sie einen asynchronen Ereignishandler haben können. Einige Semantiken einer asynchronen void -Methode unterscheiden sich jedoch geringfügig von der Semantik einer asynchronen Task oder der asynchronen Taskmethode .

Asynchrone Void-Methoden haben unterschiedliche Fehlerbehandlungssemantiken. Wenn eine Ausnahme aus einer asynchronen Task- oder asynchronen Task-Methode ausgelöst wird, wird diese Ausnahme erfasst und auf das Task-Objekt gesetzt. Bei asynchronen void Methoden gibt es kein Task-Objekt, daher werden Ausnahmen, die aus einer asynchronen void-Methode ausgelöst werden, direkt auf dem SynchronizationContext ausgelöst, der aktiv war, als die async void-Methode gestartet wurde.

Die letzten paar Sätze fassen es gut zusammen.

Lange Rede kurzer Sinn, verwenden Sie async Task für asynchrone Testmethoden.

[Test()] 
public async Task MyTest() 
{ 
    //Some code to run test 
    //Assert Something 
} 

Sie sollten wirklich einige Zeit damit verbringen, die verlinkte Artikel zu lesen. Es hat viel mehr Ressourcen in diesem Thema und es wird Ihnen helfen, die Semantik hinter async zu verstehen/erwarten

+0

Die Void-Tests würden immer noch die Ausnahme aufnehmen, wenn sie während einer Assert auftreten. Das Problem wäre nur, wenn die anderen Codezeilen einen Fehler verursachen? Ich werde jedoch zu den Rückgabetests wechseln, um sicher zu gehen. –

+1

@NoahLarky: Nein, würden sie nicht. Die "Aufgabe" ermöglicht es dem aufrufenden Code, Vervollständigung und Ausnahmen zu erkennen.'async void' in MSTest wird nicht unterstützt; Sie werden einfach nicht laufen. –

Verwandte Themen