2017-09-15 46 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

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