单元测试期望在MSTest上调用异步操作时抛出异常

时间:2011-10-01 01:15:29

标签: c# unit-testing 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;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

也许您可以将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();
    }

}

请注意,您将从AggregateException获得Task.Wait。它InnerException将是OperateAsync的例外情况。

答案 1 :(得分:1)

异常发生在另一个线程上,必须进行相应处理。有几个选择。请看看这两篇文章: