基于测试的 FakeFunction 结果
FakeFunction Results based on Test
我正在使用 tSqlt 对存储过程进行单元测试。这个存储过程连接到一个 table 值函数,该函数不带参数,结果通过 join on 子句过滤。
我正在为存储过程编写多个测试。有没有一种方法可以根据 运行.
的测试 return 不同的结果来伪造函数
我能想到的唯一解决方案是为每个测试创建一个假的,这是可能的,但有点笨拙。
我想一个理想的解决方案是在 tsqlt 中公开某种变量,它允许我确定我在哪个测试中并使用某种 case 语句或其他东西。
我想到了一个可能的解决方案。
我在测试 class 模式中创建了一个 table 并用我希望每次测试返回的结果填充它。
CREATE TABLE testcalass.fakefunction_Results
(
ID INT,
Value NUMERIC(12, 5)
)
GO
CREATE FUNCTION testcalass.fakefunction()
RETURNS @results TABLE
(
ID INT,
Value NUMERIC(12, 5)
)
BEGIN
INSERT INTO @results
SELECT ID, Value FROM testcalass.fakefunction_Results
END
GO
所以基本上,我可以在 assemble 部分的测试顶部填充函数结果。
我为此使用了以下程序。这并不理想,但有效:
CREATE PROCEDURE [tSQLt].[FakeFunction2]
@FunctionName VARCHAR(200)
, @SchemaName VARCHAR(200) = 'dbo'
, @tmpTableName VARCHAR(200)
AS
BEGIN
DECLARE @Params VARCHAR(2000);
DECLARE @NewName VARCHAR(MAX) = @FunctionName + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE @FunctionNameWithSchema VARCHAR(MAX) = @SchemaName + '.' + @FunctionName;
DECLARE @RenameCmd VARCHAR(MAX) = 'EXEC sp_rename ''' + @FunctionNameWithSchema + ''', ''' + @NewName + ''';';
DECLARE @newTbleName VARCHAR(200) = @SchemaName + '.tmp' + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE @newTblStmt VARCHAR(2000) = 'SELECT * INTO ' + @newTbleName + ' FROM ' + @tmpTableName;
EXEC tSQLt.SuppressOutput @command = @newTblStmt;
SELECT @Params = p.params
FROM
( SELECT DISTINCT ( SELECT p1.name + ' ' + type1.name + b.brk + ',' AS [text()]
FROM sys.types type1
JOIN sys.parameters p1 ON p1.system_type_id = type1.system_type_id
CROSS APPLY
( SELECT CASE WHEN type1.name LIKE '%char' OR type1.name = 'varbinary' THEN
REPLACE(
'(' + CAST(p1.max_length AS VARCHAR(5)) + ')', '-1', 'MAX')
WHEN type1.name IN ('decimal', 'numeric') THEN
'(' + CAST(p1.precision AS VARCHAR(5)) + ', '
+ CAST(p1.scale AS VARCHAR(5)) + ')'
WHEN type1.name IN ('datetime2') THEN
'(' + CAST(p1.scale AS VARCHAR(5)) + ')'
ELSE ''
END AS brk) b
WHERE p1.object_id = p.object_id
ORDER BY p1.parameter_id
FOR XML PATH('')) [parameters]
FROM sys.objects AS o
LEFT JOIN sys.parameters AS p ON p.object_id = o.object_id
LEFT JOIN sys.types AS t ON t.system_type_id = p.system_type_id
WHERE o.name = @FunctionName AND o.schema_id = SCHEMA_ID(@SchemaName)) [Main]
CROSS APPLY
(SELECT LEFT(Main.[parameters], LEN(Main.[parameters]) - 1) params) AS p;
EXEC tSQLt.SuppressOutput @command = @RenameCmd;
DECLARE @newFunctionStmt VARCHAR(MAX) = '';
SET @newFunctionStmt = 'CREATE FUNCTION [' + @SchemaName + '].[' + @FunctionName + '](' + COALESCE(@Params,'') + ')';
SET @newFunctionStmt = @newFunctionStmt + ' RETURNS TABLE AS RETURN (SELECT * FROM ' + @newTbleName + ');';
EXEC tSQLt.SuppressOutput @command = @newFunctionStmt;
END;
和用法:
INSERT INTO #table
(col1
, col2
, col3)
VALUES
('a', 'b', 'c'),
('d', 'e', 'f');
EXEC tSQLt.FakeFunction2 @FunctionName = 'function_name'
, @SchemaName = 'dbo'
, @tmpTableName = '#table';
现在,对于任何传递给该函数的参数,它总是 return 来自 #table
temp table
的值
我正在使用 tSqlt 对存储过程进行单元测试。这个存储过程连接到一个 table 值函数,该函数不带参数,结果通过 join on 子句过滤。
我正在为存储过程编写多个测试。有没有一种方法可以根据 运行.
的测试 return 不同的结果来伪造函数我能想到的唯一解决方案是为每个测试创建一个假的,这是可能的,但有点笨拙。
我想一个理想的解决方案是在 tsqlt 中公开某种变量,它允许我确定我在哪个测试中并使用某种 case 语句或其他东西。
我想到了一个可能的解决方案。
我在测试 class 模式中创建了一个 table 并用我希望每次测试返回的结果填充它。
CREATE TABLE testcalass.fakefunction_Results
(
ID INT,
Value NUMERIC(12, 5)
)
GO
CREATE FUNCTION testcalass.fakefunction()
RETURNS @results TABLE
(
ID INT,
Value NUMERIC(12, 5)
)
BEGIN
INSERT INTO @results
SELECT ID, Value FROM testcalass.fakefunction_Results
END
GO
所以基本上,我可以在 assemble 部分的测试顶部填充函数结果。
我为此使用了以下程序。这并不理想,但有效:
CREATE PROCEDURE [tSQLt].[FakeFunction2]
@FunctionName VARCHAR(200)
, @SchemaName VARCHAR(200) = 'dbo'
, @tmpTableName VARCHAR(200)
AS
BEGIN
DECLARE @Params VARCHAR(2000);
DECLARE @NewName VARCHAR(MAX) = @FunctionName + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE @FunctionNameWithSchema VARCHAR(MAX) = @SchemaName + '.' + @FunctionName;
DECLARE @RenameCmd VARCHAR(MAX) = 'EXEC sp_rename ''' + @FunctionNameWithSchema + ''', ''' + @NewName + ''';';
DECLARE @newTbleName VARCHAR(200) = @SchemaName + '.tmp' + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE @newTblStmt VARCHAR(2000) = 'SELECT * INTO ' + @newTbleName + ' FROM ' + @tmpTableName;
EXEC tSQLt.SuppressOutput @command = @newTblStmt;
SELECT @Params = p.params
FROM
( SELECT DISTINCT ( SELECT p1.name + ' ' + type1.name + b.brk + ',' AS [text()]
FROM sys.types type1
JOIN sys.parameters p1 ON p1.system_type_id = type1.system_type_id
CROSS APPLY
( SELECT CASE WHEN type1.name LIKE '%char' OR type1.name = 'varbinary' THEN
REPLACE(
'(' + CAST(p1.max_length AS VARCHAR(5)) + ')', '-1', 'MAX')
WHEN type1.name IN ('decimal', 'numeric') THEN
'(' + CAST(p1.precision AS VARCHAR(5)) + ', '
+ CAST(p1.scale AS VARCHAR(5)) + ')'
WHEN type1.name IN ('datetime2') THEN
'(' + CAST(p1.scale AS VARCHAR(5)) + ')'
ELSE ''
END AS brk) b
WHERE p1.object_id = p.object_id
ORDER BY p1.parameter_id
FOR XML PATH('')) [parameters]
FROM sys.objects AS o
LEFT JOIN sys.parameters AS p ON p.object_id = o.object_id
LEFT JOIN sys.types AS t ON t.system_type_id = p.system_type_id
WHERE o.name = @FunctionName AND o.schema_id = SCHEMA_ID(@SchemaName)) [Main]
CROSS APPLY
(SELECT LEFT(Main.[parameters], LEN(Main.[parameters]) - 1) params) AS p;
EXEC tSQLt.SuppressOutput @command = @RenameCmd;
DECLARE @newFunctionStmt VARCHAR(MAX) = '';
SET @newFunctionStmt = 'CREATE FUNCTION [' + @SchemaName + '].[' + @FunctionName + '](' + COALESCE(@Params,'') + ')';
SET @newFunctionStmt = @newFunctionStmt + ' RETURNS TABLE AS RETURN (SELECT * FROM ' + @newTbleName + ');';
EXEC tSQLt.SuppressOutput @command = @newFunctionStmt;
END;
和用法:
INSERT INTO #table
(col1
, col2
, col3)
VALUES
('a', 'b', 'c'),
('d', 'e', 'f');
EXEC tSQLt.FakeFunction2 @FunctionName = 'function_name'
, @SchemaName = 'dbo'
, @tmpTableName = '#table';
现在,对于任何传递给该函数的参数,它总是 return 来自 #table
temp table