基于Test的FakeFunction结果

问题描述 投票:0回答:2

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

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

我能想到的唯一解决方案是创建一个假的每个测试,这可能但比笨重更多。

我想一个理想的解决方案是在tsqlt中暴露的某种变量,这将允许我确定我在哪个测试并使用某种case语句或其他东西。

tsqlt
2个回答
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临时表中的值


0
投票

我想到了一个可能的解决方案。

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

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

基本上,我可以在汇编部分填充函数结果。

© www.soinside.com 2019 - 2024. All rights reserved.