基于测试的 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

的值