基于测试的FakeFunction结果

时间:2019-04-09 20:54:13

标签: tsqlt

我正在使用tSqlt对存储过程进行单元测试。此存储的proc连接到一个表值函数,该函数不带任何参数,并且结果通过join on子句进行过滤。

我正在为存储的过程编写多个测试。有没有一种伪造函数的方式,我可以根据正在运行的测试返回不同的结果。

我能想到的唯一解决方案是为每个测试创建一个伪造品,这是可能的,但比笨拙的要多。

我想象一个理想的解决方案是在tsqlt中公开某种变量,该变量将使我能够确定自己所处的测试并使用某种case语句或其他内容。

2 个答案:

答案 0 :(得分:1)

我使用以下步骤。这并不理想,但可以正常工作:

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';

现在,通过该函数传递的任何参数,它将始终返回#table临时表中的值

答案 1 :(得分:0)

我想到了一个潜在的解决方案。

我在测试类模式中创建一个表,并用希望每个测试返回的结果填充该表。

string pathToExcelFile = @"C:\workbook1.xlsx";
string workbookName = "workbook1";

var columnAMaxValue = new ExcelQueryFactory(pathToExcelFile)
                              .Worksheet<WorkSheetClass>(workbookName)
                              .Max(x => x.ColumnA);

所以基本上,我可以在汇编部分的测试顶部填充函数结果。