简体   繁体   English

如何使用NUnit处理异步void方法中的异常

[英]How to handle exceptions in async void methods with NUnit

I have some tests that run through the workflow of my WPF program. 我在WPF程序的工作流程中运行了一些测试。 I do the normal MVVM approach which is binding buttons on the view to commands on the view model, which then handles the event. 我执行普通的MVVM方法,该方法将视图上的按钮绑定到视图模型上的命令,然后再处理事件。 The way my tests test my workflow is then by directly executing the commands on the view model. 然后,通过直接在视图模型上执行命令来测试我的工作流程。 This roughly translates to look something like: 这大致翻译为:

[Test]
public void Test()
{
    var vm = new ViewModel();
    vm.AcceptCommand.Execute();
    Assert.IsTrue(stuff);
}

All of this works well, except for the fact that the code in the viewmodel that handles the command ends up being an async void method since this just becomes an event handler. 除了视图模型中用于处理命令的代码最终成为异步void方法(因为这只是成为事件处理程序)以外,所有其他方法都可以正常工作。 If an exception gets thrown here, nunit does not show a failing test because it doesn't "see" this exception in the background thread. 如果在这里抛出异常,则nunit不会显示失败的测试,因为它不会在后台线程中“看到”该异常。

My question is: is there a way to get NUnit to handle these background exceptions? 我的问题是:有没有办法让NUnit处理这些背景异常?

If it's possible then refactor your method into 2 methods. 如果可能,则将您的方法重构为2种方法。 First one should return Task and it's the one that is testable. 第一个应该返回Task,并且它是可测试的。 The other should call and await first method. 另一个应调用并等待第一个方法。 This hint is taken from Concurrency in C# Cookbook by Stephen Cleary. 此提示摘自Stephen Cleary的C#Cookbook中的Concurrency。 This is the preferred method. 这是首选方法。 This book also mentions AsyncContext class from AsyncEx library which allows to test async void methods. 本书还提到了AsyncEx库中的AsyncContext类, 该类允许测试异步void方法。

AsyncContext.Run(() =>
 { 
     // put your code here
 })

Quote from the same book: The AsyncContext type will wait until all asynchronous operations complete (including async void methods) and will propagate exceptions that they raise. 引用同一本书:AsyncContext类型将等待所有异步操作完成(包括异步void方法)并将传播它们引发的异常。

Take a look here for similar discussion: Await a Async Void method call for unit testing 看看这里进行类似的讨论: 等待异步Void方法调用进行单元测试

There is a separate method in NUnit to verify exceptions in async methods: NUnit有一个单独的方法来验证async方法中的异常:

var exception = Assert.ThrowsAsync<NotImplementedException>(() => vm.AcceptCommand.Execute());

or vice versa: 或相反亦然:

Assert.DoesNotThrowAsync(() => vm.AcceptCommand.Execute());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM