Sql server tsqlt错误处理胜过存储过程(单元)错误处理程序

Sql server tsqlt错误处理胜过存储过程(单元)错误处理程序,sql-server,unit-testing,tsqlt,Sql Server,Unit Testing,Tsqlt,当尝试在存储过程中验证用户提供的GUID时,使用了一种简单的方法;将用户输入作为字符(36),然后在TRY-CATCH中将其显式转换为唯一标识符。然后,CATCH使用RAISERROR使用自定义错误描述来冒泡错误 手动运行存储过程,所有操作都按预期执行,并引发错误 创建一个tSQLt测试来调用该单元(具有GUID验证的过程),并处理输出的错误,并与预期错误进行比较,但由于事务错误而不断失败;tSQLt检测到错误并在tSQLt框架内进行了处理 这向我表明,tSQLt正在处理转换为不同数据类型的失败

当尝试在存储过程中验证用户提供的GUID时,使用了一种简单的方法;将用户输入作为字符(36),然后在TRY-CATCH中将其显式转换为唯一标识符。然后,CATCH使用RAISERROR使用自定义错误描述来冒泡错误

手动运行存储过程,所有操作都按预期执行,并引发错误

创建一个tSQLt测试来调用该单元(具有GUID验证的过程),并处理输出的错误,并与预期错误进行比较,但由于事务错误而不断失败;tSQLt检测到错误并在tSQLt框架内进行了处理

这向我表明,tSQLt正在处理转换为不同数据类型的失败的严重性,它阻止了存储过程中的TRY/CATCH来处理它。与嵌套过程非常相似,有时会忽略子过程中的TRY/CATCH并冒泡到父过程;例如,如果子进程。引用不存在的表

有没有人有过类似的问题?只是为了验证我目前的想法

我已经删除了这个测试,并且正在其他地方进行测试,但是这给我的DB单元测试造成了一个“漏洞”

最后,我想我应该提到,我知道我可以对提供的CHAR参数(而不是CAST)执行不同的验证,并以这种方式引发错误,但这是一个tSQLt查询,而不是一个tSQL查询

编辑

代码示例:

@sGUID是一个字符(36),是传递给过程的参数

BEGIN TRY
    SELECT CAST(@sGUID AS UNIQUEIDENTIFIER)
END TRY 
BEGIN CATCH
    RAISERROR('Invalid GUID format',16,1)
END CATCH
SELECT行从不触发CATCH tSQLt,它显示为在手之前进行干预并抛出回滚事务错误。

当您调用RAISEERROR()时,您正在终止tSQLt正在运行的事务-->因此出现事务错误

为了改进单元测试的目的,您可以考虑用一个只包含RAISError()的自定义存储过程来调用RaSeError()语句。这样,就可以单独对存储过程进行单元测试

BEGIN TRY
    SELECT CAST(@sGUID AS UNIQUEIDENTIFIER)
END TRY 
BEGIN CATCH
    EXEC dbo.customprocedure
    --RAISERROR('Invalid GUID format',16,1)
END CATCH

您是否在存储过程中使用任何事务?您能否发布一些示例代码。过程中没有事务您是否验证了@sGUID为该值设置了有效的GUID格式?换句话说,一个仅由十六进制值组成的36位字符串。我已经尝试过了,它似乎起作用了——当我提供非GUID输入时,它碰到了catch块。您是否有可能正在使用旧版本,并且此版本已修复?如果您使用的是最新版本(我是)的Luminary,则repro案例可能会很有用,您能否提供一个测试程序示例以及您使用的tSQLt版本?在tSQLt如何响应使事务无效的错误方面,最近发生了一些微妙的变化,您的强制转换可能适合这些错误之一。还添加了一个tSQLt.ExpectException过程,它可能会帮助您进行测试。