如何在tSQLt中验证嵌套存储过程是否执行?排查SpyProcedure异常
解决tSQLt.SpyProcedure检测嵌套存储过程执行失败的问题
我之前也碰到过类似的情况,咱们一步步来排查和解决:
先搞清楚问题出在哪
你现在的测试用了raiserror来标记嵌套存储过程被执行,但测试没捕获到预期异常,大概率是这几个原因之一:
- 主存储过程
masterProcedureName根本没走到调用procedureName的分支(触发条件不满足); - 自定义的
raiserror没有被正确抛出到测试上下文(比如主过程里的try-catch吃掉了异常); SpyProcedure的使用方式不对,没正确替换原存储过程的逻辑。
更可靠的测试方案:用tSQLt.AssertObjectWasCalled
其实tSQLt.SpyProcedure本身就会记录存储过程的调用情况,完全不需要用异常来做判断,这种方式更直接也更稳定。给你写个完整的测试示例:
CREATE PROCEDURE [testSchema].[unitestName] AS BEGIN -- 准备:用Spy替换目标存储过程,它会自动记录调用次数 EXEC tSQLt.SpyProcedure 'procedureName'; -- 执行:触发主存储过程 EXEC masterProcedureName; -- 断言:检查嵌套存储过程是否被调用过 EXEC tSQLt.AssertObjectWasCalled 'procedureName'; END;
执行这个测试,如果主过程确实调用了procedureName,测试就会通过;如果没调用,会明确提示Expected procedureName to have been called at least once. It was called 0 times.,比异常提示更清晰。
如果你坚持要用异常的方式(不推荐)
如果一定要用raiserror来验证,那得注意两个点:
- 确保主存储过程里没有
try-catch块捕获这个异常,否则异常传不到测试层面; - 调用
SpyProcedure时要确保异常能正确抛出,比如加上WITH NOWAIT:
CREATE PROCEDURE [testSchema].[unitestName] AS BEGIN -- 准备:替换存储过程为抛出异常的逻辑 EXEC tSQLt.SpyProcedure 'procedureName', 'RAISERROR(''procedureName was fired'', 16, 1) WITH NOWAIT;'; -- 断言预期异常 EXEC tSQLt.ExpectException @ExpectedMessage = 'procedureName was fired'; -- 执行主存储过程 EXEC masterProcedureName; END;
最后排查关键点
不管用哪种方式,先确认这个前提:在当前测试环境下,执行masterProcedureName确实会调用procedureName。你可以单独执行masterProcedureName,手动检查是否触发了嵌套过程,比如看原过程的日志或者临时加个打印语句,先排除条件不满足的情况。
另外要注意:如果存储过程在非默认schema下,要加上完整的名称,比如[dbo].[procedureName],避免tSQLt找不到对象。
内容的提问来源于stack exchange,提问作者Muflix
相关产品推荐
相关产品推荐

