我正在使用tSqlt对存储过程进行单元测试。此存储的proc连接到一个表值函数,该函数不带任何参数,并且结果通过join on子句进行过滤。
我正在为存储的过程编写多个测试。有没有一种伪造函数的方式,我可以根据正在运行的测试返回不同的结果。
我能想到的唯一解决方案是为每个测试创建一个伪造品,这是可能的,但比笨拙的要多。
我想象一个理想的解决方案是在tsqlt中公开某种变量,该变量将使我能够确定自己所处的测试并使用某种case语句或其他内容。
答案 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);
所以基本上,我可以在汇编部分的测试顶部填充函数结果。