其他分享
首页 > 其他分享> > 单元测试应在MSTest上调用异步操作时引发异常

单元测试应在MSTest上调用异步操作时引发异常

作者:互联网

下面的源代码是有关我的问题的示例代码片段.我希望在调用异步操作时会发生异常.

单元测试

[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;
        }
    }
}

解决方法:

也许您可以将异步操作实现为任务,从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抛出的异常.

标签:unit-testing,mstest,c
来源: https://codeday.me/bug/20191207/2087155.html