在tSQLt中,我们可以使用AssertEqualsTable命令比较2个表。
但是,有什么方法可以断言表中的值是否已更改了一定数量?
例如:
表A:AccID |余额
表B:AccID |余额
tSQLt中有什么方法可以比较这两个表,以检查余额是否已移动一定量(例如100)?如果更改超过+/- 100并失败?
解决方法是使用通常的SQL逻辑-也就是说,我们可以在AccID上连接两个表,然后计算Balance差异,并在where子句中强制执行条件,以便仅显示差异为+/- 100的那些AccID。然后,仅当以上输出返回0条记录时,才允许测试成功。
最佳答案
tSQLt是一个单元测试框架,因此,单元测试的基本结构应为:
组装可能包括:
伪造表格,视图或函数,监视任何程序
设置任何需要预先存在的数据进行测试
定义任何预期结果集(例如,如果测试来自
视图)
并非所有测试都具有“组装”步骤
法案:
通常,这将是对存储过程或函数的调用或从视图中进行的SELECT。
如果测试表约束或触发此步骤,则可能涉及将数据插入表中
尽管不是强制性的,但大多数测试将具有“ Act”步骤,例如,“ Assemble”步骤可能伪造并填充一些驱动特定视图内容并定义预期结果的表,然后可以使用“ Assert”步骤来比较具有预期结果集的视图。
断言可能包括:
比较SELECT语句的结果,查看内容,
具有预定义结果集的函数或过程输出
检查是否引发了异常
检查是否调用了另一个存储过程(使用
tSQLt.SpyProcedure)
等等
每个测试应该(最好是准确地)有一个断言(尽管在行为之前将放置用于测试异常的代码行)。
因此,考虑到上述情况和您的要求,该数据只能根据某些操作(在过程或触发器中,或通过直接DML语句)的结果进行更改,因此您的测试必须具有“操作”步骤。我看不到如何编写tSQLt测试来断言任何数据更改都在您的容忍范围之内,而不管更改它的过程如何。您什么时候运行该测试?在哪个过程或所有过程之后?那不是单元测试,而是集成测试。实际上,可以说它实际上是应用程序/程序逻辑的一部分。
如果需要确保对值的更改永远不会超出数据库的容忍度(跨两个表),则可以尝试以下操作:
1)如果在插入或更新表A时,表A上“余额”列中的值大于或小于表B中的等效值,则使用引发异常的触发器
2)为该触发器编写第一个测试,该测试断言,如果表A中的值在您的公差范围内更改,则不会引发任何错误。该逻辑可能看起来像这样:
组装:
伪造TableA和TableB(tSQLt.Faketable
)
将触发器重新应用于伪造的TableA(tSQLt.ApplyTrigger
)
在TableA和tableB中添加一行代表您的起点
断言:
致电tSQLt.ExpectNoException
法案:
使用范围内的值更新TableA中的行
3)为该触发器编写下一个测试,该测试断言,如果表A中的值在您的容限范围之外更改,则会引发错误。
组装:
伪造TableA和TableB(tSQLt.Faketable
)
将触发器重新应用于伪造的TableA(tSQLt.ApplyTrigger
)
在TableA和tableB中添加一行代表您的起点
断言:
调用tSQLt.ExpectException
,可以选择定义预期的错误号和/或消息
法案:
使用超出您的公差级别的值更新TableA中的行。
我强烈建议您练习以测试为先的开发,因此首先编写两个测试,第一个应该通过,第二个将失败。然后,当您创建触发器时,两个测试都应该通过,并且可以证明所需的逻辑在肯定和否定情况下都是有效的。
最后,这种数据库驱动的逻辑方法的问题在于您的应用程序将不得不处理此错误。这种逻辑可能更好地放在应用程序中。数据库毕竟不是python,因此在这种情况下LBYL(请您先了解一下)比EAFP更好(更轻松地寻求许可)