如何在.NET 6环境下用Moq对GetAwaiter().GetResult()进行Mock配置?
解决方案:Mock同步等待异步方法的调用
技术环境
- .NET 6
- C# 10
- Microsoft.NET.Test.Sdk 15.5.0
- Moq 4.18.2
- Xunit 2.4.1
核心说明
你不需要单独Mock GetAwaiter().GetResult(),因为Task类型本身已经实现了这些成员。只要正确MockSendQueryAsync<TResponse>返回一个已完成的Task实例,当SUT调用GetAwaiter().GetResult()时,会自动从Task中获取预设的结果。
完整测试代码实现
public class SUTClassTests { [Fact] public void BlahTestMethod() { // 1. 创建IBlahResponse<dynamic>的Mock实例,作为方法返回结果 var mockResponse = new Mock<IBlahResponse<dynamic>>(); // 可按需配置mockResponse的成员,比如返回特定属性值 // mockResponse.Setup(r => r.SomeProperty).Returns("test"); // 2. 创建已完成的Task,用Task.FromResult比TaskCompletionSource更简洁 var completedTask = Task.FromResult(mockResponse.Object); // 3. 配置BlahClientMock的SendQueryAsync方法 var blahClientMock = new Mock<IBlahClient>(); blahClientMock.Setup(c => c.SendQueryAsync<dynamic>(5, CancellationToken.None)) .Returns(completedTask); // 4. 实例化SUT并调用目标方法 var sut = new SUTClass(); var result = sut.BlahBlahMethod(blahClientMock.Object); // 5. 验证结果(根据业务逻辑补充断言) // Assert.True(result); // 验证SendQueryAsync是否被正确调用 blahClientMock.Verify(c => c.SendQueryAsync<dynamic>(5, CancellationToken.None), Times.Once); } }
异常场景补充
如果需要模拟异步方法抛出异常的场景,可以用Task.FromException:
var failedTask = Task.FromException<IBlahResponse<dynamic>>(new InvalidOperationException("模拟异常")); blahClientMock.Setup(c => c.SendQueryAsync<dynamic>(5, CancellationToken.None)) .Returns(failedTask);
此时SUT调用GetAwaiter().GetResult()时会抛出对应的异常,方便测试错误分支。
内容的提问来源于stack exchange,提问作者crazyTech
相关产品推荐
相关产品推荐

