FakeTable с триггерами удаления tSQLt
Я только что начал использовать tSQLt и собираюсь протестировать триггер. Я вызываю процедуру FakeTable и выполняю тест, но триггер не выполняется. Если не использовать FakeTable, триггер выполняется. Кажется, это очень плохо, и я не могу найти никакой информации о том, что есть какой-либо способ их перечитать.
Затем я подумал, что триггеры удалены FakeTable, но я могу воссоздать их после вызова и сделал следующий код в моем тесте:
DECLARE @createTrigger NVARCHAR(MAX);
SELECT @createTrigger = OBJECT_DEFINITION(OBJECT_ID('MoveDataFromAToB'))
EXEC tSQLt.FakeTable 'dbo.A';
EXEC(@createTrigger);
Я получил следующую ошибку: "В базе данных уже есть объект с именем" MoveDataFromAToB ".{MoveDataFromAToB,14} (также произошла ошибка" ROLLBACK ERROR "-> текущая транзакция не может быть зафиксирована и не может быть откатлена до точки сохранения. Откатить всю транзакцию.{Private_RunTest,60})"
Кто-нибудь, кто имеет опыт работы с tSQLt и знает обходной путь для этой проблемы?
2 ответа
В резерве tSQLt есть метод ApplyTrigger, но он еще не завершен. На данный момент вы должны быть в состоянии использовать этот код в своем тесте:
DECLARE @createTrigger NVARCHAR(MAX);
SELECT @createTrigger = OBJECT_DEFINITION(OBJECT_ID('MoveDataFromAToB'));
DROP TRIGGER MoveDataFromAToB;
EXEC tSQLt.FakeTable 'dbo.A';
EXEC(@createTrigger);
Вам нужно удалить существующий триггер, так как FakeTable не удаляет исходную таблицу. Он просто переименовывает его, что оставляет старый триггер нетронутым; отсюда и столкновение имен.
Откат, который tSQLt выполняет в конце каждого теста, вернет удаленный триггер на место (если вы не делаете что-то действительно плохое в своем коде). Если вы беспокоитесь об этом, используйте sp_rename вместо drop на триггере.
Я поместил бы все это в хранимую процедуру помощника в классе теста и вызвал бы это из тестов, которые нуждаются в этом. Таким образом, когда у нас будет лучшее решение, реализованное в tSQLt, вам придется изменить только одно место в вашем коде.
Спасибо Себастьян за ваш ответ. Мне это тоже очень помогло:) Я сделал сохраненный процесс для кода, который вы дали. Я буду использовать это до тех пор, пока функция ApplyTrigger не станет доступной:
CREATE PROCEDURE [tSQLt].[FakeTableWithTrigger]
@TableName NVARCHAR(MAX),
@TriggerName NVARCHAR(MAX),
@SchemaName NVARCHAR(MAX) = NULL, --parameter preserved for backward compatibility. Do not use. Will be removed soon.
@Identity BIT = NULL,
@ComputedColumns BIT = NULL,
@Defaults BIT = NULL
AS
BEGIN
DECLARE @createTrigger NVARCHAR(MAX);
SELECT @createTrigger = OBJECT_DEFINITION(OBJECT_ID(@TriggerName));
EXEC('DROP TRIGGER ' + @TriggerName);
EXEC tSQLt.FakeTable @TableName, @SchemaName, @Identity, @ComputedColumns, @Defaults;
EXEC(@createTrigger);
END
Пример его использования в тесте:
exec tSQLt.FakeTableWithTrigger 'dbo.MyTable', 'MyTable_SyncTrigger', @Identity = 1