tsqlt是sql server存储过程单元测试的唯一可行方案,因其能完整验证临时表、output参数和错误抛出三类输出;安装需满足兼容级别≥100、启用clr(含高级选项)、trustworthy on(生产禁用);测试时须用faketable处理永久表、表变量替代临时表、显式output声明、applyconstraint解除insert exec限制,并用expectexception校验错误。

tSQLt 是 SQL Server 存储过程单元测试的唯一可行方案,其他方式在临时表、OUTPUT 参数、错误抛出三类输出上必然漏断言或难隔离。
安装 tSQLt 前必须确认的三件事
90% 的安装失败都卡在这三步没做全:
- 数据库兼容级别 ≥ 100:运行
SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME();确认,低于 100(即 SQL Server 2005 及更早)直接不支持 - 启用 CLR:
sp_configure 'clr enabled', 1; RECONFIGURE;,需sysadmin权限,且得先开高级选项:sp_configure 'show advanced options', 1; RECONFIGURE; - 开发/测试库执行
ALTER DATABASE [YourDB] SET TRUSTWORTHY ON;;生产环境禁用此设置,改用证书签名加载程序集
若报 “Could not load file or assembly”,检查 tSQLt 版本是否匹配 SQL Server 实际版本——例如 SQL Server 2019 CU20 应用 tSQLt v1.0.8+,对应 .NET Framework 4.6.1。
测试含 OUTPUT 参数或临时表的过程时怎么写才不失败
直接 EXEC 就跑,大概率断言失效,因为 tSQLt 不自动处理这两类输出:
-
CREATE TABLE #temp无效:tSQLt.FakeTable只伪造永久表;临时表逻辑得拆进独立过程,或改用表变量@table_var(tSQLt 可正常处理) - OUTPUT 参数必须显式声明变量并加
OUTPUT关键字:DECLARE @total DECIMAL(10,2); EXEC dbo.usp_GetOrderSummary @order_id = 100, @total = @total OUTPUT;,漏掉OUTPUT就捕获不到值 - 过程内部含
INSERT EXEC调用另一个过程时,tSQLt 默认禁止嵌套 EXEC;需提前用tSQLt.ApplyConstraint解除限制
验证错误抛出必须用 ExpectException,不能只看返回值
仅靠 @return_code 判断是否出错,会漏掉 RAISERROR 或 THROW 的语义级失败:
- 写法示例:
EXEC tSQLt.ExpectException @ExpectedMessage = 'Insufficient balance'; EXEC usp_TransferFunds @FromId = 1, @ToId = 2, @Amount = 100.0; -
@ExpectedMessage默认是子串匹配;要全等匹配,加参数@ExpectedMessagePattern = 0 - 要校验错误号,必须传
@ExpectedErrorNumber,否则不比对
临时表、OUTPUT、错误抛出这三类输出,任一遗漏都会让测试“看起来通过,实则失效”。tSQLt 的价值不在语法简洁,而在它强制你覆盖所有真实输出路径。











