2017-09-15 45 views
1

我试图总结我解决这个大脑,但不能让它工作,所以我在这里提出一个小测试用例,并希望有人能向我解释:tSQLt,触发器和测试

首先一点测试数据库:

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

tSQLt目前仅限于在自己的事务中运行测试,并且如您所见,在您处理其事务时反应不佳。

因此,要使此测试正常工作,您需要跳过测试内的回滚但不在外面。

我建议这种做法:

  1. 删除所有事务处理从触发语句。无论如何,您并不需要开始交易,因为触发器总是在其中执行。
  2. 如果发现有违反行,调用,它回滚,而RAISERROR
  3. 间谍为您的测试

要测试过程本身过程的过程,你可以使用tSQLt.NewConnection

+0

谢谢,塞巴斯蒂安!做得很清楚! /安德斯 –