W poprzednim wpisie pokazałem jak testować wiersze zwracane przez procedury. Niestety nie brały one pod uwagę kolejności wierszy, co może wydawać się nienaturalne. Załóżmy, że mamy następującą procedurę, zwracającą artykuły posortowane po tytule:
CREATE PROCEDURE [dbo].[GetArticles] AS BEGIN SELECT * FROM dbo.Articles ORDER BY title asc; END
Następnie analogicznie do poprzedniego wpisu, piszemy test jednostkowy:
--Assemble EXEC tSQLt.FakeTable 'dbo.Articles' INSERT INTO dbo.Articles (Title) VALUES('C'),('B'),('A') CREATE TABLE ActualValues ( Id INTEGER, Title nvarchar(10), Content nchar(500) ) CREATE TABLE ExpectedValues ( Title nvarchar(10) ) INSERT INTO dbo.ExpectedValues ( Title) VALUES ( 'A'),('B'),('C') INSERT INTO ActualValues EXEC dbo.GetArticles; --Assert EXEC tSQLt.AssertEqualsTable @Expected = N'ExpectedValues', @Actual = N'ActualValues'
Wstrzykujemy do naszego “mocka” wiersze w kolejności “C,B,A” i sprawdzamy, że na wyjściu pojawią się one w kolejności rosnącej ponieważ w procedurze mamy order by Title Asc. Odpalamy test i wszystko wydaje się w porządku. Niestety jest to błędny wniosek. Spróbujmy zmienić test do następującej postaci:
--Assemble EXEC tSQLt.FakeTable 'dbo.Articles' INSERT INTO dbo.Articles (Title) VALUES('C'),('B'),('A') CREATE TABLE ActualValues ( Id INTEGER, Title nvarchar(10), Content nchar(500) ) CREATE TABLE ExpectedValues ( Title nvarchar(10) ) INSERT INTO dbo.ExpectedValues ( Title) VALUES ('C'),('B'),('A') INSERT INTO ActualValues EXEC dbo.GetArticles; --Assert EXEC tSQLt.AssertEqualsTable @Expected = N'ExpectedValues', @Actual = N'ActualValues'
Zmieniliśmy kolejność oczekiwanych artykułów na błędną. Po uruchomieniu testu, przekonamy się, że wciąż zakończy się on sukcesem, czego oczywiście nie spodziewaliśmy się!
Niestety kolejność nie jest sprawdzana, co jak się dłużej zastanowimy ma sens, ale na pierwszy rzut oka jest mylące.
Musimy stworzyć kolumnę, która będzie identyfikowała kolejność. Naturalnym wyborem jest zatem “identity”:
--Assemble EXEC tSQLt.FakeTable 'dbo.Articles' INSERT INTO dbo.Articles (Title) VALUES('C'),('B'),('A') CREATE TABLE ActualValues ( Id INTEGER, Title nvarchar(10), Content nchar(500), OrderSequence INT IDENTITY(1,1) ) CREATE TABLE ExpectedValues ( OrderSequence INT IDENTITY(1,1), Title nvarchar(10) ) INSERT INTO dbo.ExpectedValues ( Title) VALUES ('C'),('B'),('A') INSERT INTO ActualValues EXEC dbo.GetArticles; --Assert EXEC tSQLt.AssertEqualsTable @Expected = N'ExpectedValues', @Actual = N'ActualValues'
Proszę zauważyć, że dodaliśmy OrderSequence do ExpectedValues oraz ActualValues. Po odpaleniu testu, dostaniemy błąd, ponieważ kolejność nie zgadza się:
Jeśli zmienimy ExpectedValues z powrotem do sekwencji rosnącej (A,B,C), wtedy test oczywiście zakończy się sukcesem.
Jak zatem to działa? Identity jest zwiększane automatycznie w momencie dodawania danych. Zatem ExpectedValues będzie miał wartości (1,A),(2,B) oraz (3,B). Analogicznie sprawa wygląda z ActualValues. Wynik GetArticles jest dodawany do tabeli ActualValues, która z kolei zawiera pole identity – za każdym razem OrderSequence jest zwiększane. Innymi słowy, dane musza być dodawane w tej samej kolejności, zarówno do ActualValues jak i ExpectedValues.