tSQLt应用NOT NULL约束

时间:2019-03-19 19:31:29

标签: sql sql-server tsqlt

如何将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

3 个答案:

答案 0 :(得分:1)

尝试以下操作:

UPDATE MYTABLE
SET MyColumn = 'Default Value'
WHERE MyColumn IS NULL

ALTER TABLE MYTABLE
AlTER COLUMN MyColumn DATATYPE NOT NULL

答案 1 :(得分:1)

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

对于那些不知道的人,tSQLt.FakeTable临时用一个模拟代替实表,该模拟具有相同的架构,表和列名称以及所有相同的数据类型,但没有约束。因此,所有列均允许NULL,并且在测试期间将删除所有键,默认值,检查约束甚至IDENTITY属性。当针对具有多个依赖关系的单个表编写单元测试时,这很有用-它将每个测试所需的设置最小化。在每个测试结束时,将回滚运行该测试的事务并返回原始表结构。

由于实际问题,尽管tSQLt.Fake表确实允许将原始表的某些功能(包括自动增量,计算列和默认约束)保留在模拟中,但可空性不是这些功能之一。尽管如果@SebastianMeine或@dennislloydjr正在阅读此内容,则此功能可能是有用的附加值。

我不认为没有自动的方法将NOT NULL应用于伪造的表中的列,但是这确实引起了有关您的用例的问题。尽管FakeTable在许多测试方案中非常有用,但是在某些情况下,您可能希望对实际表运行一个或多个测试。这里一个明显的例子是一个存储过程,旨在将新行插入到该表中。如果在写入插入存储过程之后将新的NOT NULL列添加到表中,则该过程将失败,因为它不会在新的必需列中插入值。您肯定希望在测试中对存储过程进行测试,并针对要在投入生产之前检测到该错误的真实表进行至少一次存储过程测试。

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

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

答案 2 :(得分:0)

在 tSQLt 测试中丢失可空性应该不是问题。您可以控制放置在伪造表格中的数据。您可以确保填充需要用于正确测试的值的列。通过在测试执行期间更改列来更改伪造表的特征会使测试的长期维护变得更加困难。

您可以创建一个私有版本的 FakeTable 来重载原始版本。这样您就可以自动恢复 NULLability 设置。 (我们有一个非常广泛的扩展模式,它重载了 FakeTable 并在不改变基本产品的情况下实现了许多其他内部功能。)缺点是现在你必须在填充测试数据时考虑所有 NOT NULL 列,这就是 FakeTable部分是为了避免。将所有列设为 NULL 可让您将测试重点放在对该测试上下文重要的列上。

您没有说明为什么要恢复 NULLability 设置。知道这会改善任何答案。