单元测试预计在调用MSTest上的异步操作时抛出异常
本文关键字:异步操作 抛出异常 MSTest 调用 单元测试 | 更新日期: 2023-09-27 18:10:06
下面的源代码是关于我的问题的示例代码片段。我期望在调用异步操作时发生异常。
单元测试[TestMethod()]
[ExpectedException(typeof(Exception))]
public void OperateAsyncTest()
{
//Arrange
var testAsyncClass = new TestAsyncClass();
//Act
testAsyncClass.OperateAsync();
}
代码public class TestAsyncClass
{
public void OperateAsync()
{
ThreadPool.QueueUserWorkItem( obj =>{
throw new Exception("an exception is occurred.");
});
}
}
但是,MsTest不能捕获异常,因为可能测试线程与抛出异常的线程不同。如何解决这个问题?任何想法?
下面的代码是我的变通方法,但它既不聪明也不优雅。解决方案
[TestClass()]
public class TestAsyncClassTest
{
private static Exception _exception = new Exception();
private static readonly EventWaitHandle ExceptionWaitHandle = new AutoResetEvent(false);
static TestAsyncClassTest()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
_exception = (Exception)e.ExceptionObject;
ExceptionWaitHandle.Set();
}
[TestMethod()]
[ExpectedException(typeof(Exception))]
public void OperateAsyncTest()
{
//Arrange
var testAsyncClass = new TestAsyncClass();
//Act
lock(_exception)
{
testAsyncClass.OperateAsync();
ExceptionWaitHandle.WaitOne();
throw _exception;
}
}
}
也许您可以将您的异步操作实现为Task
,从OperateAsync
返回,然后从调用者返回Task.Wait
?
Task.Wait
将"观察"异常,以便您的单元测试可以检测到它(如果您用ExpectedException
属性装饰它)。
代码应该是这样的:
public class TestAsyncClass {
public Task OperateAsync() {
return Task.Factory.StartNew(
() => {
throw new Exception("an exception is occurred.");
}
);
}
}
[TestClass]
public class TestAsyncClassTest {
[TestMethod]
[ExpectedException(typeof(AggregateException))]
public void OperateAsyncTest() {
var testAsyncClass = new TestAsyncClass();
testAsyncClass.OperateAsync().Wait();
}
}
注意,您将从Task.Wait
中获得AggregateException
。它的InnerException
将是你从OperateAsync
抛出的异常。
异常发生在不同的线程上,必须相应地处理。有几个选择。请看看这两篇文章:
- 异步命令模式-异常处理 异步多线程异常处理?