tSQLt – jak testować “constraints”

Załóżmy, że mamy następującą tabelę:

CREATE TABLE [dbo].[Articles](
	[Id] [int] NOT NULL,
	[Price] [int] NULL,
 CONSTRAINT [PK_Articles] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Articles]  WITH CHECK ADD  CONSTRAINT [CK_Articles] CHECK  (([Price]>(5)))
GO

ALTER TABLE [dbo].[Articles] CHECK CONSTRAINT [CK_Articles]
GO

Oprócz tabeli, dodaliśmy walidację danych. Cena zawsze musi być większą niż 5. Jeśli spróbujemy dodać wartość mniejszą niż 5, zakończy się to błędem.

INSERT INTO Articles Values(1,4)

Błąd:

The INSERT statement conflicted with the CHECK constraint "CK_Articles". The conflict occurred in database "testdb", table "dbo.Articles", column 'Price'.

Spróbujmy teraz wykonać taką samą operację w teście:

EXEC tSQLt.FakeTable 'dbo.Articles'
INSERT INTO Articles Values(1,4)

Dodanie wartości 4 nie spowoduje żadnego błędu. Wynika to z tego, że każdy stub pozbawiony jest jakichkolwiek restrykcji. Zwykle jest to bardzo korzystne, ponieważ jeśli testujemy tylko jedną kolumnę, nie musimy martwić się o resztę wartości.
Jeśli z kolei chcemy, aby nasze testy pokryły również walidację danych (constraints), wtedy mamy do dyspozycji metodę ApplyConstraint:

EXEC tSQLt.FakeTable 'dbo.Articles'
EXEC tSQLt.ApplyConstraint @TableName='dbo.Articles', @ConstraintName="CK_Articles"

INSERT INTO Articles Values(1,4)

Dzięki ApplyConstraint możemy dodawać ograniczenia jedno po drugim, co umożliwia prawidłową implementację testów jednostkowych, gdzie chcemy testować wyłącznie pojedyncze rzeczy. Prawidłowa implementacja testu wygląda zatem następująco:

EXEC tSQLt.FakeTable 'dbo.Articles'
EXEC tSQLt.ApplyConstraint @TableName='dbo.Articles', @ConstraintName="CK_Articles"

EXEC tSQLt.ExpectException

INSERT INTO Articles Values(1,4)

Analogicznie, powinniśmy przetestować wartości, które są zgodne z wymaganiami:

EXEC tSQLt.FakeTable 'dbo.Articles'
EXEC tSQLt.ApplyConstraint @TableName='dbo.Articles', @ConstraintName="CK_Articles"

EXEC tSQLt.ExpectNoException

INSERT INTO Articles Values(1,10)

Testowanie kluczy obcych odbywa się również za pomocą ApplyContraint. Bardzo podobną metodą jest ApplyTrigger:

tSQLt.ApplyTrigger [@TableName = ] 'table name'
                    , [@TriggerName = ] 'trigger name'

Leave a Reply

Your email address will not be published.