Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing xUnit异步测试工作不正常_Unit Testing_Async Await_Xunit - Fatal编程技术网

Unit testing xUnit异步测试工作不正常

Unit testing xUnit异步测试工作不正常,unit-testing,async-await,xunit,Unit Testing,Async Await,Xunit,我们从一开始就在项目中使用xUnit框架作为测试框架。目前项目中有2200多个单元测试,一切都很好 但昨天我决定在CI构建和夜间构建中运行单元测试。与team build controller一起运行xunit测试1-2个小时,我成功地运行了测试。但有一个问题,有22个关于如下测试的警告, -Xunit.Sdk.EqualException:Assert.Equal()失败 或 -System.ArgumentNullException:值不能为null 经过进一步研究,我意识到这些测试必须失败

我们从一开始就在项目中使用xUnit框架作为测试框架。目前项目中有2200多个单元测试,一切都很好

但昨天我决定在CI构建和夜间构建中运行单元测试。与team build controller一起运行xunit测试1-2个小时,我成功地运行了测试。但有一个问题,有22个关于如下测试的警告, -Xunit.Sdk.EqualException:Assert.Equal()失败 或 -System.ArgumentNullException:值不能为null

经过进一步研究,我意识到这些测试必须失败,但似乎通过了,因为所有这些测试都标有“async”关键字

实际上不应该有任何错误,因为xUnit支持关于这些帖子的异步测试 然而,现实对我来说差别不大。是的,xUnit运行没有任何问题,但测试不正确

这里有两个小方法

public async Task<string> AsyncTestMethod() {
    throw new Exception("Test");
}
public string NormalTestMethod() {
    throw new Exception("Test");
}
  [Fact]
    public async void XunitTestMethod_Async() {
        Program p = new Program();
        string result = await p.AsyncTestMethod();
        Assert.Equal("Ok", result);
    }
        [Fact]
    public  void XunitTestMethod_Normal() {
        Program p = new Program();
        string result =  p.NormalTestMethod();
        Assert.Equal("Ok", result);
    }
两个原始方法都会抛出异常,所以我认为两个测试都应该失败,但结果不同。您可以看到以下结果:

XunitTestMethod\u异步测试通过,但XunitTestMethod\u正常失败。 抛出异常不是这种情况,您可以根据需要更改方法内容AsyncTestMethod始终通过

以下是示例解决方案:

我可能会误解或认为错误,但现在这种行为给我带来了很多痛苦

希望你能启发我

PS:我在XUnitGithub页面上创建了一个问题,但我不能确定这是由我还是xUnit引起的。所以我也决定在这里提问。
问题:

问题在于
async void
方法不返回xUnit可能检查异常的
Task
对象。xUnit甚至无法跟踪特定的
异步void
方法的完成情况,而不是
异步任务
方法

此外,
async void
方法不会在同一堆栈帧上抛出异常,即使是从方法的同步部分抛出的异常也是如此。相反,异常通过
SynchronizationContext.Post
(如果
SynchronizationContext.current!=null
)或通过
ThreadPool.QueueUserWorkItem
传播到当前同步上下文。此行为不同于
异步任务
方法。可以跟踪挂起的
async void
方法的总数(通过
SynchronizationContext.OperationStarted
/
OperationCompleted
),但不能跟踪单个方法

因此,将
XunitTestMethod\u Async
方法的签名从
Async void
更改为
Async Task
应该可以解决问题


更新了,现在是2019年,@maracuja juice指出,两个
异步void
测试现在都失败了,因为它们本来应该是这样的。xUnit团队已经实现了他们独特的同步上下文,一个他们用来单独跟踪每个
async void
调用并捕获任何异常的实例。

尝试将
async void
签名更改为
async任务
。我记得以前看到过一个类似的问题被问到和回答过,但我没有发现。我想答案不会这么简单。如果你发表你的评论,我愿意接受。非常感谢。关于
async void
非常有趣和奇怪,但它确实有意义。我偶然发现了这个问题,但我很高兴读到它。这在今天仍然成立吗?@maracuja juice,我相信是的,但我不使用xUnit。你能试着报告吗?@maracuja juice,哪些失败,
async void
?现在他们似乎有了自己的实例,每个
async void
方法调用都必须安装一个实例,但两个测试都失败了。这正是人们所期望的。