如何在不打开数据库连接的情况下用OrmLite单元测试数据层存储过程/函数?
无需真实数据库连接的OrmLite存储过程单元测试方案
你完全可以在不打开真实数据库连接的前提下完成单元测试,核心思路是模拟OrmLite的执行流程,绕过实际数据库调用,彻底摆脱对PostgreSQL真实连接的依赖。以下是具体实现方案:
关键优化方向
- 不再依赖真实的
OrmLiteConnection,直接用Moq模拟IDbConnection对象 - 自定义
OrmLiteExecFilter拦截存储过程SQL调用,直接返回预设结果 - 移除需要真实连接的
OrmLiteConnectionFactory初始化逻辑
完整测试代码
[Fact] public async Task TestMyMethod_CallsMyStoredProcedure() { // Arrange var mockConnFac = new Mock<IDashboardDbConnectionFactory>(); var mockDbConn = new Mock<IDbConnection>(); // 设置全局执行过滤器,拦截所有SQL执行 OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter(); // 模拟连接工厂返回Mock连接(无需打开真实数据库) mockConnFac.Setup(m => m.OpenAsync(It.IsAny<ISecurityContext>())) .ReturnsAsync(mockDbConn.Object); mockConnFac.Setup(m => m.Open(It.IsAny<ISecurityContext>())) .Returns(mockDbConn.Object); // Act var target = new MyDataLayerCLass(mockConnFac.Object, new NullLoggerFactory()); bool testResult = await target.ExecMyStoredProcAsync(new Mock<ISecurityContext>().Object, Guid.NewGuid()); // Assert Assert.True(testResult); } private class MockStoredProcExecFilter : OrmLiteExecFilter { // 拦截同步执行逻辑 public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter) { var cmd = filter.Target as IDbCommand; // 匹配目标存储过程SQL,返回预设测试结果 if (cmd?.CommandText == "select central_data.my_stored_function(@UserId, @ParentId)") { return (T)(object)true; } // 非目标SQL可根据测试需求抛出异常或返回默认值 throw new NotSupportedException("仅支持测试目标存储过程"); } // 拦截异步执行逻辑 public override async Task<T> Exec<T>(IDbConnection dbConn, Func<IDbCommand, Task<T>> filter) { var cmd = filter.Target as IDbCommand; if (cmd?.CommandText == "select central_data.my_stored_function(@UserId, @ParentId)") { return await Task.FromResult((T)(object)true); } throw new NotSupportedException("仅支持测试目标存储过程"); } }
核心原理说明
- Mock连接对象:用Moq创建
IDbConnection的模拟实例,不需要初始化真实的OrmLiteConnection,自然也不需要有效的数据库连接字符串。 - 拦截执行流程:自定义
MockStoredProcExecFilter覆盖OrmLiteExecFilter的Exec方法,直接检查待执行的SQL语句,匹配目标存储过程时返回预设结果,完全跳过实际数据库调用。 - 简化配置:无需自定义方言提供器,直接设置全局
OrmLiteConfig.ExecFilter即可生效。
这种实现完全脱离真实数据库依赖,属于纯单元测试,不受数据库状态影响,测试执行效率更高。
内容的提问来源于stack exchange,提问作者devlord
相关产品推荐
相关产品推荐

