tSQLt В Private_RunTest также произошла ошибка ROLLBACK
Всякий раз, когда я использую ExpectException, я получаю следующую ошибку: (Также произошла ошибка ROLLBACK -> Текущая транзакция не может быть принята и не может быть откатлена до точки сохранения. Откат всей транзакции.{Private_RunTest,140})
Похоже, что tSQLt пытается выполнить ROLLBACK после того, как MSSQL уже выполнил ROLLBACK из-за RAISERROR. Я обернул следующий оператор SELECT и SET в Private_RunTest следующим оператором IF, и это, похоже, решило проблему.
IF ISNULL(@ExpectException,0) <> 1
BEGIN
SELECT @Msg = COALESCE(@Msg, '') + ' (There was also a ROLLBACK ERROR --> ' +
COALESCE(ERROR_MESSAGE(), '') + '{' +
COALESCE(ERROR_PROCEDURE(), '') + ',' +
COALESCE(CAST(ERROR_LINE() AS NVARCHAR), '') + '})';
SET @Result = 'Error';
END
Это действительно ошибка и / или подходящее исправление?
2 ответа
Вы, вероятно, не используете блоки TRY/CATCH в своем тесте tsqlt.
Сообщение об ошибке "ROLLBACK ERROR -> Текущая транзакция не может быть зафиксирована и ее нельзя откатить до точки сохранения. Откатить всю транзакцию." Можно воспроизвести следующим образом:
1) Создайте триггер, который выдает ошибку и откатывается следующим образом:
CREATE TRIGGER [dbo].[MyTable_IUDTR] ON [dbo].[MyTable]
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
BEGIN TRY
RAISERROR('MyError', 16, 1)
END TRY
BEGIN CATCH
THROW;
END CATCH
END
GO
2) Создайте тест tsqlt, чтобы проверить возвращаемое сообщение об ошибке:
CREATE PROC [ut_MyTable_IUDTR].[test that the error is returned]
AS
BEGIN
DECLARE @ErrorMsg VARCHAR(50)
EXEC tsqlt.FakeTable @TableName = 'MyTable'
EXEC tsqlt.ApplyTrigger 'MyTable', 'MyTable_IUDTR'
INSERT INTO dbo.MyTable
( FirstName, LastName )
VALUES ( N'John',N'Smith')
SET @ErrorMsg = ERROR_MESSAGE()
EXEC tSQLt.AssertEqualsString @Expected = 'MyError', @Actual = @ErrorMsg
END
GO
3) Запустите тест:
EXEC [tSQLt].Run 'ut_MyTable_IUDTR.test that the error is returned'
4) Вы получаете следующую ошибку:
There was also a ROLLBACK ERROR --> The current transaction cannot be committed and cannot be rolled back to a savepoint. Roll back the entire transaction.
ИСПРАВЛЕНИЕ:
Измените тест tsqlt, чтобы включить блоки TRY/CATCH следующим образом:
ALTER PROC [ut_MyTable_IUDTR].[test that the error is returned]
AS
BEGIN
DECLARE @ErrorMsg VARCHAR(50)
EXEC tsqlt.FakeTable @TableName = 'MyTable'
EXEC tsqlt.ApplyTrigger 'MyTable', 'MyTable_IUDTR'
BEGIN TRY
INSERT INTO dbo.MyTable
( FirstName, LastName )
VALUES ( N'John',N'Smith')
END TRY
BEGIN CATCH
SET @ErrorMsg = ERROR_MESSAGE()
END CATCH
EXEC tSQLt.AssertEqualsString @Expected = 'MyError', @Actual = @ErrorMsg
END
GO
Вы можете использовать SET XACT_ABORT ON
в вашем тесте tsqlt
CREATE PROC [testClass]. [Test foo] КАК НАЧАТЬ SET XACT_ABORT ON EXEC tsqlt.AssertEquals @Expected = 1, @Actual = 0 КОНЕЦ
Не делай этого.
Вы получите сообщение, подобное этому
[testClass].[test foo] failed: (Error) Expected: <1> but was: <0> (There was also a ROLLBACK ERROR --> The current transaction cannot be committed and cannot be rolled back to a savepoint. Roll back the entire transaction.{Private_RunTest,160})