我最近调用了一个在代码中包含rasierror的过程。raiserror位于try catch块中。在raiserror之后,BEGIN TRAN也在相同的try catch块中。Catch块用于在事务中发生错误时回滚事务。它这样做的方法是检查@@TRANCOUNT是否大于0,我知道它已经启动了一个事务,需要回滚。在使用tSQLt进行测试时,@@TRANCOUNT始终大于0,因此如果它命中CATCH块,则会执行ROLLBACK,并且tSQLt会失败(因为tSQLt正在事务中运行)。当我遇到错误并且CATCH块正在运行时,tSQLt总是无法通过测试。我没有办法测试raiserror的正确处理。如何创建可能回滚事务的测试用例?
发布于 2012-01-24 04:08:21
正如您所提到的,tSQLt在其自己的事务中运行每个测试。为了跟踪正在发生的事情,需要在测试结束时仍然打开相同的事务。SQL Server不支持嵌套事务,因此您的过程将回滚所有内容,包括框架为当前测试存储的状态信息。在这一点上,tSQLt只能假设发生了非常糟糕的事情。因此,它将测试标记为错误。
SQL Server本身不鼓励在过程内进行回滚,因为如果在打开的事务内调用该过程,则会引发错误。有关处理这种情况的方法和一些其他信息,请查看我关于how to rollback in procedures的博客文章。
发布于 2015-03-01 07:19:21
因为我正在阅读tSQLt,当我了解到每个测试都运行在一个事务中时,这是我想到的第一个问题之一。由于我的一些存储过程确实启动了事务,有些甚至使用嵌套事务,这可能会变得具有挑战性。我所学到的关于嵌套事务的知识,如果你应用以下规则,你可以保持你的代码干净的常量错误检查,并且仍然优雅地处理错误。
除非引发错误,否则在打开transactions
记住这些规则,这里是一个proc实现和测试代码的示例。
ALTER PROC testProc
@IshouldFail BIT
AS
BEGIN TRY
BEGIN TRAN
IF @IshouldFail = 1
RAISERROR('failure', 16, 1);
COMMIT
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK;
-- Do some exception handling
-- You'll need to reraise the error to prevent exceptions about inconsistent
-- @@TRANCOUNT before / after execution of the stored proc.
RAISERROR('failure', 16, 1);
END CATCH
GO
--EXEC tSQLt.NewTestClass 'tSQLt.experiments';
--GO
ALTER PROCEDURE [tSQLt.experiments].[test testProc nested transaction fails]
AS
BEGIN
--Assemble
DECLARE @CatchWasHit CHAR(1) = 'N';
--Act
BEGIN TRY
EXEC dbo.testProc 1
END TRY
BEGIN CATCH
IF @@TRANCOUNT = 0
BEGIN TRAN --reopen an transaction
SET @CatchWasHit = 'Y';
END CATCH
--Assert
EXEC tSQLt.AssertEqualsString @Expected = N'Y', @Actual = @CatchWasHit, @Message = N'Exception was expected'
END;
GO
ALTER PROCEDURE [tSQLt.experiments].[test testProc nested transaction succeeds]
AS
BEGIN
--Act
EXEC dbo.testProc 0
END;
GO
EXEC tSQLt.Run @TestName = N'tSQLt.experiments'发布于 2014-03-19 21:22:53
最好在BEGIN TRANSACTION之后使用BEGIN TRY块。当我遇到类似的问题时,我这样做了。这更符合逻辑,因为在CATCH块中,我检查了IF @@TRANCOUNT > 0 ROLLBACK。如果在BEGIN TRANSACTION之前引发了另一个错误,则不需要检查此条件。在这种情况下,您可以测试您的RAISERROR功能。
https://stackoverflow.com/questions/8973138
复制相似问题