如何在tSQLt中模拟SERVERPROPERTY函数以适配SQL Server版本分支逻辑
tSQLt模拟SERVERPROPERTY函数的实现方法
完全可以实现,tSQLt内置的tSQLt.FakeFunction存储过程专门用于对标量函数做模拟,支持覆盖包括SERVERPROPERTY在内的系统内置函数,刚好满足你需要模拟不同SQL Server版本的测试场景。
核心实现逻辑
SERVERPROPERTY是系统标量函数,接收1个SYSNAME类型的参数,返回SQL_VARIANT类型的结果。你只需要自定义一个和原函数输入输出类型完全一致的替身函数,在替身函数里指定不同测试场景下的返回值,再用tSQLt.FakeFunction做替换即可。模拟仅在当前测试事务内生效,测试结束后会自动回滚,不会影响实际业务和其他测试。
完整测试示例
1. 先准备待测试的业务逻辑示例
假设你有一段根据SQL Server主版本号判断新特性是否支持的函数:
CREATE OR ALTER FUNCTION dbo.CheckNewFeatureSupport() RETURNS BIT AS BEGIN DECLARE @MajorVersion INT = CAST(SERVERPROPERTY('ProductMajorVersion') AS INT); -- SQL Server 2019对应的主版本号为15,要求2019及以上版本支持新特性 RETURN IIF(@MajorVersion >= 15, 1, 0); END; GO
2. 编写tSQLt测试用例
第一步:创建测试类和替身函数
-- 创建测试类 EXEC tSQLt.NewTestClass 'TestVersionRelatedLogic'; GO -- 定义替身函数,和SERVERPROPERTY的输入输出类型完全一致 CREATE OR ALTER FUNCTION TestVersionRelatedLogic.Mock_ServerProperty(@PropertyName SYSNAME) RETURNS SQL_VARIANT AS BEGIN -- 模拟SQL Server 2019的返回值 IF @PropertyName = 'ProductMajorVersion' RETURN CAST(15 AS INT); -- 可根据测试需要扩展其他属性的模拟返回值 RETURN NULL; END; GO
第二步:编写测试验证高版本场景
CREATE OR ALTER PROCEDURE TestVersionRelatedLogic.Test_WhenSQL2019_ReturnFeatureSupported AS BEGIN -- 替换系统SERVERPROPERTY为我们的模拟函数 EXEC tSQLt.FakeFunction @FunctionName = N'SERVERPROPERTY', @FakeFunctionName = N'TestVersionRelatedLogic.Mock_ServerProperty'; -- 执行业务逻辑 DECLARE @Result BIT = dbo.CheckNewFeatureSupport(); -- 断言结果符合预期 EXEC tSQLt.AssertEquals 1, @Result; END; GO
第三步:扩展低版本测试场景
如果要验证SQL Server 2016(主版本号13)下特性不支持的场景,只需要新增一个替身函数或者修改替身函数的返回值即可:
CREATE OR ALTER FUNCTION TestVersionRelatedLogic.Mock_ServerProperty_2016(@PropertyName SYSNAME) RETURNS SQL_VARIANT AS BEGIN IF @PropertyName = 'ProductMajorVersion' RETURN CAST(13 AS INT); RETURN NULL; END; GO CREATE OR ALTER PROCEDURE TestVersionRelatedLogic.Test_WhenSQL2016_ReturnFeatureNotSupported AS BEGIN EXEC tSQLt.FakeFunction @FunctionName = N'SERVERPROPERTY', @FakeFunctionName = N'TestVersionRelatedLogic.Mock_ServerProperty_2016'; DECLARE @Result BIT = dbo.CheckNewFeatureSupport(); EXEC tSQLt.AssertEquals 0, @Result; END; GO
注意事项
- 替身函数的输入参数数量、类型,返回值类型必须和原
SERVERPROPERTY完全一致,否则模拟会失效 - 所有模拟操作都在tSQLt的测试事务内执行,测试跑完会自动回滚,不会篡改系统函数的实际行为
- 如果需要在单个测试里动态修改
SERVERPROPERTY的返回值,可以通过临时表传递参数给替身函数,实现更灵活的模拟逻辑
内容的提问来源于stack exchange,提问作者tarun_
相关产品推荐
相关产品推荐

