pva*_*ten 5 t-sql sql-server tsqlt
我有一个多次使用 GETUTCDATE() 函数的存储过程。这是一个非常具体的业务流程,所以在这里展示它可能没有多大意义。话虽如此,了解 sproc 只会在今年被调用可能会有所帮助。这是一个人为的例子,它没有显示我正在做的事情的复杂性,但应该有助于说明我在说什么:
CREATE PROCEDURE dbo.GenerateRequestListForCurrentYear AS BEGIN
SELECT RequestId, StartDate, EndDate FROM Requests
WHERE YEAR(EndDate) = YEAR(GETUTCDATE());
END;
Run Code Online (Sandbox Code Playgroud)
我的测试是这样的:
CREATE PROCEDURE testClass.[test Requests are generated for the current year] AS BEGIN
-- arrange
EXEC tSQLt.FakeTable 'dbo.Requests';
INSERT INTO dbo.Requests (RequestId, StartDate, EndDate) VALUES
(1, '2/1/14', '2/10/14'), (2, '2/1/13', '2/10/13');
SELECT TOP (0) * INTO #Expected FROM dbo.Requests;
SELECT TOP (0) * INTO #Actual FROM dbo.Requests;
INSERT INTO #Expected VALUES
(1, '2/1/14', '2/10/14');
-- act
INSERT INTO #Actual
EXEC dbo.GenerateRequestListForCurrentYear;
-- assert
EXEC tSQLt.AssertEqualsTable #Expected, #Actual;
END;
Run Code Online (Sandbox Code Playgroud)
我看到几个选项:
这两个似乎都是测试所必需的选项,看起来有点臭;永远不需要根据主应用程序如何调用此 sproc 来参数化它。
由于它与 SQL 中具有自己的依赖关系的内置函数的依赖关系有关,有没有办法在 tSQLt 测试中伪造这些调用?有没有更好的方法来伪造对 GETUTCDATE() 的调用以返回我在使用 tSQLt 的测试中指定的日期,或者这些是我唯一的选择吗?
您可以使用任何一种方法,并且像安德鲁一样,我过去也使用过这两种方法。
不过,只要有可能,我通常更喜欢选项 1(传递参数)。它的另一个好处是使执行更具可重复性。换句话说,我可以传递任意日期,这通常对支持很有用,并且不止一次使添加新功能变得更加容易。我发现这对于 SQL 之外的语言也很有用。它的作用是使单个复杂代码的结果不依赖于它的执行时间,而是依赖于接收到的参数和系统中的数据。换句话说,除了测试将当前时间作为参数传递之外,还有一个好处,可以减轻您的犹豫。(需要指出的是,我也相信做出支持测试的设计决策并没有什么错——它是产品的重要组成部分)。
选项 2 也有效,您只需创建自己的函数来包装系统函数即可。但是您应该意识到,这可能会对性能产生影响,您应该对其进行彻底测试。当查询涉及函数时,SQL Server 并不总是对你友善。由于假定的性能问题,我不喜欢在查询中永远不要使用标量函数的建议,因为有时不会造成性能损失,有时性能差异不是问题。但是,如果您决定包装该函数,您应该意识到其潜力。
| 归档时间: |
|
| 查看次数: |
1074 次 |
| 最近记录: |