首页 > 解决方案 > tSQLt 应用 NOT NULL 约束

问题描述

如何将 NOT NULL 约束应用回 tSQLt 中表的列?

CREATE OR ALTER PROCEDURE [test abc].[test abc1]
AS
BEGIN
    -- Arrange
    EXEC tSQLt.FakeTable 'dbo', 'table1';
    -- Here the NOT NULL constraint should be put back on table1 column col1
    EXEC [tSQLt].[ExpectNoException]
    -- Act + Assert
    INSERT INTO .....
END
GO

标签: sqlsql-servertsqlt

解决方案


OP 专门询问如何在 tSQLt 单元测试的上下文中执行此操作。

对于那些不知道的人,tSQLt.FakeTable 临时用一个模拟替换了一个真实的表,该模拟具有相同的模式、表和列名以及所有相同的数据类型,但没有任何约束。因此,所有列都允许为 NULL,并且在测试期间删除所有键、默认值、检查约束甚至 IDENTITY 属性。在针对具有许多依赖项的单个表编写单元测试时,这可能很有用 - 它最大限度地减少了每个测试所需的设置。在每个测试结束时,运行该测试的事务将回滚并返回原始表结构。

现在回到实际问题,虽然 tSQLt.Fake 表确实允许在模拟中保留原始表的某些特性,包括自动增量、计算列和默认约束,但可空性不是这些特性之一。尽管如果@SebastianMeine 或@dennislloydjr 正在阅读本文,那么这样的功能可能是一个有用的增值。

我不相信没有自动方法将 NOT NULL 应用于伪造表中的列,但是它确实提出了关于您的用例的问题。虽然 FakeTable 在许多测试场景中非常有用,但在某些情况下,您可能希望针对真实表运行一个或多个测试。这里最明显的例子是一个存储过程,旨在向该表插入一个新行。如果在写入插入存储过程之后将新的 NOT NULL 列添加到表中,则该过程将失败,因为它没有将值插入到新的强制列中。您肯定希望在测试中选择它,并针对真实表对该存储过程进行至少一次测试,以便在您投入生产之前检测到该错误。

如果您的用例要求仅将特定列设置回 NOT NULL,那么您可以UPDATE myTable ALTER COLUMN myColumn <datatype> NOT NULL在调用 tSQLt.FakeTable 后手动执行此操作,尽管这种方法的危险是如果该列的数据类型或可空性将来发生变化,您将无法自动更改测试中的列定义 - 这会降低测试的可靠性。

很抱歉,您的问题没有简单的答案。


推荐阅读