c# - 异步方法中的单元测试异常
问题描述
我正在尝试使用 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;
}
}
}
解决方案
了解异步方法的工作原理以了解这里发生了什么很重要。所有异步方法都开始同步运行,就像任何其他方法一样。但在第一次await
作用于不完整Task
时,该方法返回。通常它会返回自己的Task
,然后调用者可以等待。
但是如果方法签名是async void
,那么它什么也不返回。此时,该方法还没有完成运行,但调用方法永远不会知道它何时或是否完成。
这可能就是这里发生的事情。该方法在遇到第一个await
并认为测试成功完成时返回。它永远不会看到稍后抛出的异常。
修复方法是返回 a Task
,因此可以等待该方法:
public static async Task Divide(int v1, int v2)
唯一合法的用途async void
是用于事件处理程序,因为您别无选择,只能制作void
. 但它通常也可以,因为事件应该是“哦,顺便说一句”,并且事件处理程序的成功完成通常不会影响任何调用它的进一步操作(但有一些例外) .
推荐阅读
- php - 如何将不存在的数据页面重定向到 Codeignitor 中未找到的页面?
- amazon-web-services - 如何从 Lambda 函数正确地将数据添加到 AWS amplify DynamoDb
- python - 如何在 Pandas 中限制从“羽毛”文件中读取的行数?
- google-cloud-spanner - Spanner 客户端是否支持批量插入?
- javascript - 多个字符串匹配而不使用javascript中的每个函数
- azure-data-explorer - 表查询慢 | 哪里 x | 按时间戳排序 | 不同的 a,b,c,d | 桌子大时取 20
- linux - 在 SUSE linux 中检查可升级包列表的命令是什么?
- javascript - Javascript localStorage for-loop的问题
- php - Wordpress 背景革命滑块在升级时中断
- python - Python selenium - AttributeError:'dict'对象没有属性'get_attribute'