C#单元测试Mock数据库Handler时触发NullReferenceException求助
报错根因
共有三个问题会触发本次空引用异常:
- 你仅Mock了
IConfiguration.GetSection的返回值,但没有对IConfigurationSection.Get<SigSettings>()方法配置返回规则,即使构造函数判空后会实例化新的SigSettings,默认实例的Signals属性如果没有赋值会为null,传入QueryAsync时可能触发空引用。 QueryAsync是Dapper提供的扩展方法,Moq默认无法直接Mock接口的扩展方法,你没有为该方法配置返回值,调用后默认返回null,也会触发空引用。- 测试用例没有对异步方法
GetSignals做await调用,会导致异常无法被正常捕获,出现不符合预期的报错。
修复步骤
步骤1:配置IConfigurationSection的返回值
在测试类的构造函数中,为_configSectionMock添加Get<SigSettings>的返回配置,确保_settings.Signals有有效值:
public SignalsTest() { // 原有配置保留 _configMock.Setup(x => x.GetSection(It.IsAny<string>())).Returns(_configSectionMock.Object); // 新增配置:返回填充好的SigSettings实例 _configSectionMock.Setup(x => x.Get<SigSettings>()).Returns(new SigSettings { // 填入测试用的合法SQL语句即可 Signals = "SELECT IDTag, Name FROM SigSignal" }); // 原有实例化逻辑保留 _handler = new SignalsHandler(_configMock.Object, _connection.Object); }
步骤2:Mock Dapper的QueryAsync扩展方法
推荐安装NuGet包Moq.Dapper,可以直接对Dapper的扩展方法做Mock配置,在测试类构造函数中添加如下配置:
// 引入命名空间 using Moq.Dapper; public SignalsTest() { // 原有配置保留 // 新增:配置QueryAsync的返回值 var testData = new List<SigSignal> { new SigSignal { IDTag = "tag_001", Name = "信号1" }, new SigSignal { IDTag = "tag_002", Name = "信号2" } }; _connection.SetupDapperAsync(conn => conn.QueryAsync<SigSignal>( It.IsAny<string>(), It.IsAny<object>(), It.IsAny<IDbTransaction>(), It.IsAny<int?>(), It.IsAny<CommandType?>())) .ReturnsAsync(testData); _handler = new SignalsHandler(_configMock.Object, _connection.Object); }
步骤3:修复异步测试用例
将测试方法改为异步返回Task,并await调用GetSignals方法,确保异常可以被正常捕获:
// 对应你的测试框架添加特性,比如xUnit用[Fact],NUnit用[Test] public async Task CanGetAllSignals() { var result = await _handler.GetSignals(); Assert.IsNotNull(result); // 可选:验证返回结果和Mock的测试数据一致 Assert.AreEqual(2, result.Count); }
内容的提问来源于stack exchange,提问作者Weenhallo
相关产品推荐
相关产品推荐

