XUnit ThrowsAsync<>未校验异常类型,这是Bug吗?
XUnit ThrowsAsync<>未正确校验异常类型的原因及解决办法
这不是XUnit的Bug,是你的代码存在问题——测试方法是同步的void返回值,但调用了异步的ThrowsAsync却未等待其执行完成。
Assert.ThrowsAsync<>方法会返回一个Task对象,如果你不通过await等待这个任务完成,测试方法会直接结束,根本不会执行完整的异常校验逻辑。这就导致不管抛出什么类型的异常,测试都会“假通过”。
修正后的代码
将测试方法改为异步的async Task返回值,并等待ThrowsAsync的执行:
public class AssertThrowsTests { [Fact] public async Task Tests() { await Assert.ThrowsAsync<ArgumentException>(async () => await MethodThatThrows()); } async Task MethodThatThrows() { await Task.Delay(100); throw new NotImplementedException(); } }
原理说明
当测试方法标记为async Task时,XUnit会自动等待整个异步流程执行完毕。此时ThrowsAsync会正确校验抛出的异常类型,你的测试会如预期失败——因为实际抛出的NotImplementedException与预期的ArgumentException类型不匹配。
如果一定要用同步测试方法(不推荐),可以调用Wait()方法强制等待异步任务完成:
[Fact] public void Tests() { Assert.ThrowsAsync<ArgumentException>(async () => await MethodThatThrows()).Wait(); }
但async/await是异步代码的标准写法,更易读且能避免潜在的线程阻塞问题。
内容的提问来源于stack exchange,提问作者Display name
相关产品推荐
相关产品推荐

