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

.NET Core 2.0依赖注入下控制器单元测试依赖为空问题

解决SearchController单元测试中依赖为Null的问题

我来帮你排查并解决这个单元测试里的依赖为null的问题,咱们一步步拆解问题:

问题根源分析

你的单元测试代码里有几个明显的问题,导致控制器构造函数接收的依赖为null,或者无法正确获取配置值:

  1. 变量名拼写错误
    你在测试里定义了Mock<IEmpUow> EmpUow = new Mock<IEmpUow>();,但实例化控制器时却写了oneSoeUow.Object——这个oneSoeUow根本没定义!编译器没报错可能是因为你之前有同名变量,但实际传入的是未初始化的null,这直接导致IEmpUow依赖为null。

  2. IOptions未正确初始化
    你Mock了IOptions<AppSettingsConfig>和IOptions<ConnectionStringsConfig>,但没有给它们的Value属性赋值。控制器里直接取options.Value,如果Mock的对象没有设置Value,那这个值就是null,自然控制器里的appSettings和connectionString都会是null。

  3. 控制器内属性名拼写错误
    你控制器的Test方法里写的是this.appsettings.enableDummyData,但构造函数里赋值的是this.appSettings = options.Value;(注意大写的S),这个拼写错误会导致运行时抛出空引用异常,因为appsettings是未定义的变量。

  4. 异步测试方法的不规范写法
    你的测试方法是public async void Test1(),异步测试应该用public async Task Test1(),否则测试框架可能不会等待异步操作完成,不过这是次要问题。


修复后的单元测试代码

下面是修正后的完整测试代码,我还优化了IOptions<T>的初始化方式(对于配置实体类,直接用Options.Create()比Mock更简单可靠):

public async Task Test1() // 改为async Task,符合异步测试规范
{
    // Arrange
    // 1. 初始化配置实体,设置测试需要的属性值
    var testAppSettings = new AppSettingsConfig
    {
        enableDummyData = true // 根据测试需求设置值
    };

    var testConnectionStrings = new ConnectionStringsConfig
    {
        // 按需设置连接字符串,比如测试用的模拟值
    };

    // 2. 初始化各个依赖的Mock实例
    var mockHostingEnv = new Mock<IHostingEnvironment>();
    var telemetryClient = new TelemetryClient();
    var mockLogger = new Mock<ILogger<SearchController>>();
    var mockLookupSearch = new Mock<ILookupSearch>();
    var mockFullSearch = new Mock<IFullSearch>();
    var mockEmpUow = new Mock<IEmpUow>(); // 修正变量名,避免拼写错误

    // 3. 正确初始化IOptions<T>:用Options.Create直接包装配置实体
    var connectionStringOptions = Options.Create(testConnectionStrings);
    var appSettingsOptions = Options.Create(testAppSettings);

    // Act
    var searchController = new SearchController(
        mockLookupSearch.Object,
        mockFullSearch.Object,
        mockEmpUow.Object, // 使用正确的变量名
        mockLogger.Object,
        telemetryClient,
        mockHostingEnv.Object,
        connectionStringOptions,
        appSettingsOptions
    );

    var actionResult = searchController.Test();

    // Assert
    // 根据测试需求添加断言,比如验证返回结果不为null
    Assert.NotNull(actionResult);
    // 如果需要验证SearchEmpData的调用逻辑,可以给对应的依赖Mock设置预期
}

控制器代码的小修正

别忘了修正控制器里的拼写错误,把this.appsettings.enableDummyData改成this.appSettings.enableDummyData,避免空引用异常:

[Route("Test")]
[ActionName("Test")]
[HttpGet]
public IActionResult Test()
{
    // 修正属性名的大小写
    if(this.appSettings.enableDummyData){ 
        return this.SearchEmpData(new EmpIdQueryField() { Country = "Sweden", EMPID = 441150 });
    }
    // 建议添加默认返回值,比如return Ok(); 避免方法无返回路径的编译警告
    return Ok();
}

关键修复总结

  • 确保所有依赖变量名拼写一致,避免传入未定义的变量导致null
  • 对于IOptions<T>类型,优先使用Options.Create()创建实例,而不是Mock,这样能直接传入配置实体的测试值
  • 检查控制器内的属性名拼写,避免因大小写问题导致的空引用
  • 异步测试方法使用async Task代替async void,保证测试框架能正确处理异步逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:23:31