tSQLt,触发器和测试

时间:2017-09-15 11:56:47

标签: triggers transactions tsqlt raiserror

我试图将我的大脑包裹起来,但无法使其发挥作用,所以我在这里提出了一个小测试用例,希望有人可以向我解释一下:

首先是一个小测试数据库:

CREATE DATABASE test;
USE test;
CREATE TABLE testA (nr INT)
GO

CREATE TRIGGER triggerTestA
ON testA
FOR INSERT AS BEGIN
  SET NOCOUNT ON;
  IF EXISTS (SELECT nr FROM Inserted WHERE nr > 10)
    RAISERROR('Too high number!', 16, 1);
END;

这是一个tSQL测试,用于测试行为:

ALTER PROCEDURE [mytests].[test1] AS
BEGIN
  EXEC tSQLt.FakeTable @TableName = N'testA'
  EXEC tSQLt.ApplyTrigger  
    @TableName = N'testA', 
    @TriggerName ='triggerTestA'
  EXEC tSQLt.ExpectException
  INSERT INTO dbo.testA VALUES (12)
END;

此测试运行正常 - 但触发器无法执行我想要的操作:阻止用户输入值> 10.这个版本的触发器做我想要的:

CREATE TRIGGER triggerTestA
ON testA FOR INSERT AS BEGIN
  SET NOCOUNT ON;
  BEGIN TRANSACTION;
  BEGIN TRY
    IF EXISTS (SELECT nr FROM Inserted WHERE nr > 10)
      RAISERROR('Too high number!', 16, 1);
    COMMIT TRANSACTION;
  END TRY
  BEGIN CATCH
    ROLLBACK TRANSACTION;
    THROW;
  END CATCH;
END;

但是现在测试失败,说明A)存在错误(预期!)和B)没有BEGIN TRANSACTION匹配ROLLBACK TRANSACTION。我猜这个最后一个错误是关于tSQLt周围的事务,并且我的触发器以某种方式干扰了它,但它肯定不是我所期望的。

有人可以解释,也许可以帮助我做对吗?

1 个答案:

答案 0 :(得分:1)

tSQLt目前仅限于在自己的事务中运行测试,并且正如您所看到的那样,当您调整其事务时,它会不受欢迎。

因此,要使此测试工作,您需要跳过测试中的回滚,但不要跳到外部。

我建议采用这种方法:

  1. 从触发器中删除所有事务处理语句。无论如何都不需要开始事务,因为触发器总是在一个内部执行。
  2. 如果发现违规行,请调用执行回滚和raiserror的过程
  3. 间谍测试程序
  4. 要测试该过程本身,您可以使用tSQLt.NewConnection