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 测试用例和正常的嵌套事务过程
下面是我的存储过程测试用例代码片段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 测试用例和正常的嵌套事务过程