如何实例化带基类构造参数的类?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
相关产品推荐
相关产品推荐

