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

Function App单元测试:GetInput与数据仓储返回失效问题排查

问题分析与解决

核心问题

业务代码硬编码实例化仓储,未提供依赖注入入口,导致单元测试中的Mock仓储无法替换真实仓储,Mock配置完全不生效。同时测试代码还存在接口不匹配、拼写错误等问题。

业务代码问题点

  1. 静态方法Repository()直接new RepoData(),无依赖注入设计,单元测试无法拦截实例化过程。
  2. 变量引用错误:Guid.Parse(entitydataobject.Guid)应为Guid.Parse(eventDetails.Guid),否则编译报错。
  3. Processor方法无返回值,测试中的Assert.IsTrue(result.Result)会因默认返回false失败。

测试代码问题点

  1. Mock接口不匹配:业务代码依赖IRepoData,但测试Mock的是IRepository;方法名也不匹配,业务用GetEntityList,测试Setup的是GetEntityIdList。
  2. Mock仓储未注入:测试代码未将Mock实例传入业务逻辑,业务仍调用真实仓储构造。
  3. 拼写错误:Mock<IDurableOrchestrationContest>应为Mock<IDurableOrchestrationContext>;mockContext.Setup返回的entitydataobject应为inputData。
  4. 缺少测试特性:测试方法未加[TestMethod],无法被测试框架识别。

修复步骤

1. 重构业务代码,支持依赖注入

修改Processor方法,添加仓储参数用于注入,兼容原有生产逻辑:

namespace program
{
    [FunctionName("Processor")]
    // 添加IRepoData参数,支持依赖注入
    public static async Task<bool> Processor([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log, IRepoData repo = null)
    {
        var eventDetails = context.GetInput<entitydataobject>();
        List<Guid> list;
        try
        {
            // 优先使用注入的仓储,无注入则创建默认实例
            repo = repo ?? Repository();
            // 修正变量引用错误
            list = repo.GetEntityList(Guid.Parse(eventDetails.Guid), eventDetails.Name);
            
            // 根据业务逻辑补充返回值,示例返回true
            return true;
        }
        catch(Exception ex)
        {
            log.LogError("Processor Error: " + ex.Message);
            // 异常场景返回false
            return false;
        }
    }
    
    public static IRepoData Repository() 
    {
        try
        {
            return new RepoData("Data Source=instance.local;Initial Catalog=database;integrated security=True;MultipleActiveResultSets=True;");
        }
        catch (Exception ex)
        {
            throw new Exception("Repository Error: " + ex.Message);
        }
    }
}

2. 修正单元测试代码,注入Mock仓储

namespace Test 
{ 
    [TestClass] 
    [ExcludeFromCodeCoverage] 
    public class ProcessorTests 
    {
        [TestMethod]
        public async Task Processor_ValidInput_ReturnsTrue()
        {
            // 修正拼写错误
            var mockContext = new Mock<IDurableOrchestrationContext>();      
            var inputData = JsonConvert.DeserializeObject<entitydataobject>(File.ReadAllText("file.json"));      
            var list = new List<Guid> { new Guid(), new Guid() };      
            // 修正Mock接口为IRepoData
            var mockRepo = new Mock<IRepoData>();      
            var log = new Mock<ILogger>();       

            // 匹配业务代码的方法名和参数
            mockRepo.Setup(repo => repo.GetEntityList(
                Guid.Parse(inputData.Guid), 
                inputData.Name
            )).Returns(list);      
            
            // 修正返回变量
            mockContext.Setup(x => x.GetInput<entitydataobject>()).Returns(inputData); 

            // 将Mock仓储传入Processor方法
            var result = await program.Processor(mockContext.Object, log.Object, mockRepo.Object);
            
            Assert.IsTrue(result);                
        }
    }
}

3. 关键说明

  • 通过可选参数实现依赖注入,既兼容生产环境原有逻辑,又给单元测试提供Mock入口。
  • 统一接口、方法名和变量引用,确保测试与业务逻辑匹配。
  • 添加[TestMethod]特性,让测试框架识别并执行测试。

内容的提问来源于stack exchange,提问作者HumblePirate

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:13:19