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
Другие вопросы по тегам