2016-11-21 4 views
0

Я прилагал все усилия, чтобы следовать мудрости в http://www.sommarskog.se/share_data.html и документации tSQLt; пытаясь сохранить мои хранимые процедуры светлыми и относительно некомплексными, чтобы они легко проверялись. Итак, я обнаружил, что создаю временную таблицу в первичной хранимой процедуре, а затем работаю в этой временной таблице во вторичных хранимых процедурах, вызываемых из первичной. Это работает очень хорошо, но это оказывается немного неудобным для тестирования.Тестирование хранимой процедуры, которая работает на временной таблице вызывающего абонента

При тестировании «вторичной» хранимой процедуры в изоляции временная таблица должна существовать. Похоже, что создание временной таблицы в процедуре [Set Up] не сохраняется для модульных тестов, но создание полной таблицы делает.

Таким образом, чтобы избежать повторения CREATE TABLE #temp в каждом модульном тесте (с полным определением столбца), я делаю вариацию следующее:

EXEC tSQLt.NewTestClass 'SEtest'; 
GO 

CREATE PROCEDURE [SEtest].[SetUp] 
AS 
BEGIN 
    CREATE TABLE SEtest.temptemplate (col1 int); 
END; 
GO 

CREATE PROCEDURE [SEtest].[test example] 
AS 
BEGIN 
    -- Assemble 
    SELECT TOP (0) * INTO #temp FROM SEtest.temptemplate; 
    INSERT INTO #temp (col1) 
    VALUES (1),(2),(5),(7); 

    -- Act 
    EXEC dbo.REMOVE_EVEN_NUMBERS; 

    -- Assert 
    SELECT TOP (0) * INTO #expected FROM #temp; 
    INSERT INTO #expected (col1) 
    VALUES (1),(5),(7); 

    EXEC tSQLt.AssertEqualsTable '#expected', '#temp'; 
END; 
GO 

Есть ли более эффективные способы помирить tSQLt с обменом данные между хранимыми процедурами через временные таблицы?

+0

«Я обнаружил, что создаю временную таблицу в первичной хранимой процедуре, а затем работаю в этой временной таблице в« вторичных »хранимых процедурах, вызываемых из первичной» - я избегаю этого шаблона, где это возможно. Как только реализация «утечек» из хранимой процедуры становится сложнее поддерживать и тестировать. Встроенная функция оценки таблицы часто может быть решением –

+0

Митч, я должен не согласиться. В этом контексте определение таблицы #temp является частью контракта между sproc и вызывающим.Таким образом, это не усложняет процедуру, если у вас есть правильные тесты. Однако я согласен, что он немного уродлив (но иногда T-SQL уродливый). –

+0

Единственное, что я могу придумать, может быть улучшением - это постоянная таблица с ключом процесса. До тех пор, пока я не возражаю против небольшого повышения производительности, не находящегося в tempdb, и имея дополнительный объект в базе данных, я могу, вероятно, просто использовать FakeTable в тестах, как обычно. – NReilingh

ответ

2

Существует не лучший способ.

Использование таблицы #temp в качестве ссылки на значение таблицы по умолчанию является уродливым в T-SQL и приводит к уродству в тестах. Тем не менее, ваши тесты кажутся хорошо продуманными и должны доставлять то, что вы ищете.

Единственное улучшение вашего шаблона, которое я предлагаю, заключается в том, чтобы создать таблицу SEtest.temptemplate в тестовой схеме на постоянной основе, вместо того, чтобы воссоздавать ее «на лету» каждый раз при запуске теста.

Использование SELECT ... INTO для создания тестовых таблиц - это шаблон, который я использую повсюду в своих тестах. И поскольку вы не можете создавать временные таблицы в подпроцедурах, это единственный чистый вариант, который у нас есть.

В любом случае не используйте в своих тестах инструкцию CREATE TABLE, чтобы создать таблицу #temp, так как это станет кошмаром обслуживания, если схема таблицы когда-либо изменится.


Update:

Существует одна альтернатива, которую вы могли бы хотеть рассмотреть. Поскольку ваша таблица #temp в основном является параметром таблицы, было бы неплохо использовать тип таблицы. Теперь, что еще неуклюжий, но это увеличивает ремонтопригодность на все концах:

DECLARE @template AS dbo.tabletype; 
SELECT * INTO #temptable FROM @template; 

Это делает немного более ясную читаемость, особенно если имя вашего типа таблицы выразительно (и это в той же схеме, что и процедура, о которой идет речь).

С этим вы можете использовать один и тот же шаблон в любой процедуре вызова, а не только на тестах. Это также делает фактический код немного более очевидным/читаемым и уменьшает работу по техническому обслуживанию, если определение таблицы должно когда-либо изменяться.

+0

Обновлено, чтобы добавить дополнительную идею, которая делает код более очевидным. –