如何断言异步调用同步部分时长及总时长范围?
用Fluent Assertions实现异步方法的三重时序验证
Fluent Assertions本身没有直接断言异步方法初始同步部分耗时的内置API,但可以通过自定义测量逻辑,结合单次任务调用来同时完成三种时序验证:
实现思路
- 调用异步方法时,立即记录开始时间,拿到返回的
Task对象(此时异步方法的同步部分已经执行完毕),记录同步阶段结束时间,算出同步耗时。 - 等待
Task完成后,记录总耗时的结束时间,算出总耗时。 - 用Fluent Assertions分别对同步耗时、总耗时的最小值和最大值做断言。
代码示例
第一步:封装测量辅助方法
using System.Diagnostics; public static async Task<(TimeSpan SyncDuration, TimeSpan TotalDuration)> MeasureAsync(Func<Task> asyncMethod) { var syncStart = Stopwatch.GetTimestamp(); var task = asyncMethod(); // 执行异步方法的同步部分 var syncEnd = Stopwatch.GetTimestamp(); var syncDuration = TimeSpan.FromTicks(syncEnd - syncStart); await task; // 等待异步部分执行完成 var totalEnd = Stopwatch.GetTimestamp(); var totalDuration = TimeSpan.FromTicks(totalEnd - syncStart); return (syncDuration, totalDuration); }
第二步:编写测试用例
// 待测试的异步方法示例 async Task MyAsyncOperation() { // 模拟初始同步操作(比如参数校验、本地计算) Thread.Sleep(120); // 模拟异步操作(比如IO、远程调用) await Task.Delay(250); } // 测试逻辑 var (syncTime, totalTime) = await MeasureAsync(() => MyAsyncOperation()); // 断言初始同步部分不超过150ms syncTime.Should().BeLessThanOrEqualTo(TimeSpan.FromMilliseconds(150)); // 断言总时长至少350ms(同步120+异步250的最小预期) totalTime.Should().BeGreaterThanOrEqualTo(TimeSpan.FromMilliseconds(350)); // 断言总时长不超过450ms(避免异步部分超时) totalTime.Should().BeLessThanOrEqualTo(TimeSpan.FromMilliseconds(450));
关键说明
- 整个流程只调用了一次目标异步方法,完全符合“单次任务调用/await覆盖三种验证”的要求。
- 使用
Stopwatch.GetTimestamp()保证时间测量的精度,比DateTime.Now更适合性能断言场景。 - 若要验证带返回值的异步方法,只需把
Func<Task>改成Func<Task<T>>,调整辅助方法的返回值即可。
内容的提问来源于stack exchange,提问作者tg73
相关产品推荐
相关产品推荐

