如何Mock TaskOrchestrationContext.CallHttpAsync测试.NET孤立Azure函数
解决.NET孤立模式下Durable Function中CallHttpAsync的Mock问题
在.NET孤立模式的Durable Function编排器里,CallHttpAsync是扩展方法,Moq没法直接Mock扩展方法,这就是你测试报错的原因——之前进程内模型的实现逻辑不同,所以能那么写,但孤立模式行不通。
给你两个可行的解决方案:
方案一:把Http调用封装成Activity函数,Mock CallActivityAsync
核心思路是把Http请求逻辑抽离到单独的Activity中,这样编排器只调用CallActivityAsync,而这个方法是TaskOrchestrationContext的实例方法,可以直接Mock。
重构后的编排器代码
using Microsoft.Azure.Functions.Worker; using Microsoft.DurableTask; using System.Net.Http; using System.Threading.Tasks; namespace Functions.Triggers.Orchestration.StudentEnrollments { public class SimpleOrchestrator { [Function("O_Simple")] public async Task<bool> RunAsync([OrchestrationTrigger] TaskOrchestrationContext ctx) { // 调用封装好的Activity var statusCode = await ctx.CallActivityAsync<System.Net.HttpStatusCode>("A_CallLearnUrl", null); return statusCode == System.Net.HttpStatusCode.OK; } } // 新增的Http调用Activity public class HttpCallActivity { private readonly HttpClient _httpClient; // 依赖注入HttpClient public HttpCallActivity(HttpClient httpClient) { _httpClient = httpClient; } [Function("A_CallLearnUrl")] public async Task<System.Net.HttpStatusCode> RunAsync([ActivityTrigger] object input) { var response = await _httpClient.GetAsync("https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=linux"); return response.StatusCode; } } }
对应的单元测试代码
using Microsoft.DurableTask; using Moq; using Functions.Triggers.Orchestration.StudentEnrollments; using System.Net; using Xunit; namespace tests.UnitTests { public class SimpleTest { [Fact] public async Task Test_SimpleTestOrchestrator() { var orchestrator = new SimpleOrchestrator(); var mockContext = new Mock<TaskOrchestrationContext>(); // Mock CallActivityAsync,预设返回OK状态码 mockContext .Setup(x => x.CallActivityAsync<HttpStatusCode>("A_CallLearnUrl", null, default)) .ReturnsAsync(HttpStatusCode.OK); var result = await orchestrator.RunAsync(mockContext.Object); Assert.True(result); } } }
方案二:用DurableTask.Testing包的TestOrchestrationContext
DurableTask官方提供了专门的测试上下文,不用手动Mock,直接就能模拟Http调用的返回结果,更简洁。
步骤1:安装NuGet包
Install-Package DurableTask.Testing
单元测试代码
using DurableTask.Testing; using Functions.Triggers.Orchestration.StudentEnrollments; using System.Net; using System.Net.Http; using Xunit; namespace tests.UnitTests { public class SimpleTest { [Fact] public async Task Test_SimpleTestOrchestrator() { var orchestrator = new SimpleOrchestrator(); var testContext = new TestOrchestrationContext(); // 预设指定Url的Http响应 testContext.SetupHttpResponse( HttpMethod.Get, new Uri("https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=linux"), new HttpResponseMessage(HttpStatusCode.OK)); var result = await orchestrator.RunAsync(testContext); Assert.True(result); } } }
内容的提问来源于stack exchange,提问作者Chris Rockwell
相关产品推荐
相关产品推荐

