tSQLt.ExceptException 未在 SQL 服务器中处理回滚事务

tSQLt.ExceptException is not working with rollback transaction in SQL Server

下面是我的存储过程测试用例代码片段my_proc,用于检查传递给存储过程的非空参数。

--faking required tables here

--set values of parameters to be passed
DECLARE @LINK_ID            INT = null -- required parameter which is passed null
          , @LINK_TYPE          VARCHAR(250) = 'GTN_ALERT_OPERATIONS'
          , @FILE_NAME          VARCHAR(250) = 'XML.png'
          , @FILE_SIZE          VARCHAR(250) = '2060'
          , @FILE_DATA          VARBINARY(MAX) = null
          , @FILE_TYPE          VARCHAR(10) = 'PNG'
          , @MODUKE_KEY         VARCHAR(20)  ='GTN'
          , @USER_ID            INT = 1
          , @ORGANIZATION_ID    INT = 1
          , @UPDATEDATE         datetime = getdate()    
          , @ERR_STATUS         SMALLINT = 0
          , @ERR_MSG            VARCHAR(MAX) = ''
          , @ERR_STATUS_EXPECTED SMALLINT = 2

EXEC tsqlt.ExpectException @ExpectedMessagePattern ='%Cannot insert the value NULL into column ''LINK_ID''%'

BEGIN TRY
        EXEC my_proc @LINK_ID = @LINK_ID, @LINK_TYPE = @LINK_TYPE, @FILE_NAME = @FILE_NAME, @FILE_SIZE = @FILE_SIZE
                           , @FILE_DATA = @FILE_DATA, @FILE_TYPE = @FILE_TYPE, @MODUKE_KEY = @MODUKE_KEY, @USER_ID = @USER_ID
                           , @ORGANIZATION_ID = @ORGANIZATION_ID, @ERR_STATUS = @ERR_STATUS OUT, @ERR_MSG = @ERR_MSG OUT
END TRY
BEGIN CATCH 
        IF @@TRANCOUNT = 0
        begin
            BEGIN TRAN --reopen an transaction as it gave error due to rollack called in my_proc
        end
END CATCH

如果这里的@LINK_ID 不是可为空的参数,那么它应该抛出类似

的异常

Cannot insert null ..

正如我上面提到的。所以在这里它运行良好并且结果通过。

但即使我更改了一些随机消息而不是“无法插入 null..”,此测试也通过了,这在理想情况下是错误的。它应该会失败。

这是由于 my_proc 中使用的内部事务导致的,它执行回滚 tran 出错。

请提出可能的解决方案。

如果您的代码回滚 tSQLt 事务,则所有赌注都将取消(可以这么说)。 tSQLt 在表中维护大量元数据,这些元数据将受到强制回滚的影响。

tSQLt 将正确地在测试中出错,如果您保留按原样“死亡”的事务(如您在评论中所述)。但是,如果您重新创建一个新事务,它将进入未记录状态并且可能通过或失败。

您试图通过“重新打开”事务来隐藏的错误告诉您您的体系结构有问题:

一般来说,存储过程不应该回滚它没有打开的事务。您可以在此处找到更多相关信息:How to rollback in procedures

附带说明:您目前正在“吃掉”TRY...CATCH 中的异常。所以 tSQLt 将永远无法看到它,即使您删除了 ROLLBACK.

我终于得到了问题的答案,这将有助于 tsqlt 测试用例和正常的嵌套事务过程

https://dba.stackexchange.com/a/82697/213662