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

如何实例化带基类构造参数的类?xUnit单元测试遇空引用异常

解决Workflow类单元测试中构造函数的配置依赖问题

方案1:在测试项目中添加配置项

直接在测试项目的App.config里添加对应配置节点,让ConfigurationManager.AppSettings["ConfigurationFilesLocation"]获取有效值:

<configuration>
  <appSettings>
    <add key="ConfigurationFilesLocation" value="C:\TestConfig" />
  </appSettings>
</configuration>

同时修改测试方法为异步(因为UnhandException是async Task类型):

[Fact]
public async Task UnhandledExceptionTest()
{
    // Arrange
    var workflow = new Workflow();
    var mockModule = new Mock<ModuleInterface>();
    var testException = new Exception("Test exception");

    // Act
    await workflow.UnhandException(mockModule.Object, testException);

    // Assert
    // 根据UnhandException的实际业务逻辑添加断言,比如验证日志调用、状态变更等
}

方案2:重构Workflow类,解耦配置依赖

如果可以修改原代码,推荐给Workflow添加带参数的构造函数,直接接收配置路径,避免直接依赖ConfigurationManager:

public class Workflow : WorkFlowManager
{
    // 保留原无参构造函数,兼容现有业务代码
    public Workflow() : this(Path.Combine(ConfigurationManager.AppSettings["ConfigurationFilesLocation"], confFileName))
    {
    }

    // 新增带参数构造函数,专供测试和依赖注入使用
    public Workflow(string configPath) : base(configPath)
    {
        this.RegistrationOutput = new Output();
    }

    public override async Task UnhandException(ModuleInterface module, Exception ex)
    {
        // 业务逻辑实现
    }
}

测试时直接传入测试用路径,完全脱离配置文件依赖:

[Fact]
public async Task UnhandledExceptionTest()
{
    // Arrange
    var testConfigPath = Path.Combine(Path.GetTempPath(), "TestConfig.xml");
    var workflow = new Workflow(testConfigPath);
    var mockModule = new Mock<ModuleInterface>();
    var testException = new Exception("Test exception");

    // Act
    await workflow.UnhandException(mockModule.Object, testException);

    // Assert
    // 按方法实际行为添加断言,比如验证是否调用了日志服务等
}

方案3:测试中动态设置ConfigurationManager(适用于无法修改原代码的场景)

如果不能改动原Workflow类,可以在测试初始化时临时设置配置值,测试结束后恢复原有配置,避免影响其他测试用例:

[Fact]
public async Task UnhandledExceptionTest()
{
    // Arrange:保存原有配置,设置测试用值
    var originalConfig = ConfigurationManager.AppSettings["ConfigurationFilesLocation"];
    ConfigurationManager.AppSettings["ConfigurationFilesLocation"] = "C:\TestConfig";

    try
    {
        var workflow = new Workflow();
        var mockModule = new Mock<ModuleInterface>();
        var testException = new Exception("Test exception");

        // Act
        await workflow.UnhandException(mockModule.Object, testException);

        // Assert
        // 添加对应的断言逻辑
    }
    finally
    {
        // 清理:恢复原有配置状态
        if (originalConfig == null)
        {
            ConfigurationManager.AppSettings.Remove("ConfigurationFilesLocation");
        }
        else
        {
            ConfigurationManager.AppSettings["ConfigurationFilesLocation"] = originalConfig;
        }
    }
}

注意事项

  • 测试方法必须声明为async Task,不能用void,否则异步代码不会等待执行完成,导致测试结果不准确。
  • 如果UnhandException方法内有依赖其他服务(比如日志、交互服务),可以用Moq创建对应Mock对象,通过构造函数注入或其他方式传入Workflow类,再验证Mock对象的调用行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:40:41