5

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

手动运行存储过程,一切都按预期执行,并引发错误。

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

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

有没有人有类似的问题?只是为了验证我目前的思路。

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

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

编辑

代码示例:

@sGUID 是一个 CHAR(36) 并且是传递给过程的参数。

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

SELECT 行从不触发 CATCH tSQLt 似乎事先干预并引发 ROLLBACK 事务错误。

4

1 回答 1

0

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

为了单元测试的目的而改进这一点,您可能考虑的一个选项是将 RAISEERROR() 语句替换为对包含 RAISERROR() 的自定义存储过程的调用。这样,您可以单独对该存储过程进行单元测试。

BEGIN TRY
    SELECT CAST(@sGUID AS UNIQUEIDENTIFIER)
END TRY 
BEGIN CATCH
    EXEC dbo.customprocedure
    --RAISERROR('Invalid GUID format',16,1)
END CATCH
于 2013-10-10T18:09:28.893 回答