【发布时间】:2017-04-04 07:25:48
【问题描述】:
我一直在尽力遵循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 与通过临时表在存储过程之间共享数据?
【问题讨论】:
-
“我发现自己在主存储过程中创建了一个临时表,然后在从主存储过程调用的“辅助”存储过程中对该临时表进行操作”——我在任何地方都避免使用这种模式可能的。一旦实现从存储过程中“泄漏”出来,维护和测试就会变得更加困难。内联表值函数通常是一种解决方案
-
米奇,我不同意。在这种情况下,#temp 表的定义是存储过程和调用者之间契约的一部分。因此,如果您有正确的测试,它不会使程序更难维护。但是,我同意它有点丑(但有时 T-SQL 很丑)。
-
我唯一能想到的可能是改进的方法是一个进程键控的永久表。只要我不介意不驻留在 tempdb 中并且在数据库中有一个额外的对象对性能的轻微影响,我可能可以像往常一样在测试中使用 FakeTable 它。
标签: sql-server unit-testing stored-procedures tsqlt