You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:33:21