You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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来验证,那得注意两个点:

  1. 确保主存储过程里没有try-catch块捕获这个异常,否则异常传不到测试层面;
  2. 调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:04:43