首页 > 解决方案 > 异步方法中的单元测试异常

问题描述

我正在尝试使用 VSTest 对下面的异步方法进行单元测试。但是,即使仅在第一种情况下抛出异常,测试AsyncMathsStatic.Divide(4, 0)也会通过。AsyncMathsStatic.Divide(4, 1))

[TestClass]
public class UnitTest1
{
    [TestMethod]

    public void DivideTest1()
    {
        // Func<Task> action = async()=> {  AsyncMathsStatic.Divide(4, 0); };
        //action.Should().Throw<DivideByZeroException>();

        Assert.ThrowsExceptionAsync<DivideByZeroException>(async () => 
        AsyncMathsStatic.Divide(4, 0));
    }
}

public class AsyncMathsStatic
{
    public static async void Divide(int v1, int v2)
    {
        try
        {
            if (v1/v2 > 1)
            {
                // do something time consuming
            }   
        }
        catch (DivideByZeroException ex)
        {
            throw;
        }
    }
}

标签: c#exceptionasync-awaitvstest

解决方案


了解异步方法的工作原理以了解这里发生了什么很重要。所有异步方法都开始同步运行,就像任何其他方法一样。但在第一次await作用于不完整Task时,该方法返回。通常它会返回自己的Task,然后调用者可以等待。

但是如果方法签名是async void,那么它什么也不返回。此时,该方法还没有完成运行,但调用方法永远不会知道它何时或是否完成。

这可能就是这里发生的事情。该方法在遇到第一个await并认为测试成功完成时返回。它永远不会看到稍后抛出的异常。

修复方法是返回 a Task,因此可以等待该方法:

public static async Task Divide(int v1, int v2)

唯一合法的用途async void是用于事件处理程序,因为您别无选择,只能制作void. 但它通常也可以,因为事件应该是“哦,顺便说一句”,并且事件处理程序的成功完成通常不会影响任何调用它的进一步操作(但有一些例外) .


推荐阅读