这是关于tSQLt / SQL测试最佳实践的问题。
假设我有一个存储过程,它返回一个简单SELECT语句的结果,例如
SELECT
A.Column1
, B.Column2
FROM
TableA AS A
INNER JOIN
TableB AS B
ON
A.ID = B.ID
;
我正在考虑要编写的tSQLt测试。最明显的测试是我在两个表中都有记录(具有匹配的ID),并且该过程返回正确的数据。
该测试是否足够?可能不是,因为有人可以将INNER JOIN更改为LEFT JOIN,并且测试仍然会通过,但存储过程的行为现在已经改变。
因此,如果TableA或TableB为空,或者两个表都为空,那么我是否应该测试是否没有返回任何记录?虽然我认为这更完整,但它对我来说有点过分,并且可能导致对包含5个或更多表的SELECT语句进行可怕的测试。
我很感激社区的想法。
谢谢,
灰
答案 0 :(得分:2)
确保有一个内部联接更少。因为我们不想确切地指定存储过程的实现方式。但是,我们确实希望始终按预期返回存储过程的预期结果。
我的测试看起来像这样:
CREATE PROCEDURE [MyTests.SimpleTests].[test Returns_SimpleTable_Successfully]
AS
BEGIN
--Arrange
EXEC tSQLt.FakeTable @schemaname = 'dbo', @tablename = 'TableA';
EXEC tSQLt.FakeTable @schemaname = 'dbo', @tablename = 'TableB';
INSERT INTO TableA (Id, Column1) VALUES (1, 'Value1'),(2, 'Value2')
INSERT INTO TableB (Id, Column2) VALUES (1, 'Value3'),(3, 'Value4')
CREATE TABLE Expected
(
Column1 NVARCHAR(255),
Column2 NVARCHAR(255)
)
INSERT Expected (Column1, Column2)
VALUES (N'Value1', N'Value3');
--Act
CREATE TABLE Actual
(
Column1 NVARCHAR(255),
Column2 NVARCHAR(255)
)
INSERT Actual (Column1, Column2)
EXEC up_SimpleTest
--Assert
EXEC tSQLt.AssertEqualsTable 'Expected', 'Actual'
END;
正在测试的存储过程如下所示:
CREATE PROC up_SimpleTest
AS
BEGIN
SELECT
A.Column1,
B.Column2
FROM TableA AS A
RIGHT JOIN TableB AS B
ON A.Id = B.Id;
END
这意味着如果存储过程更改为LEFT,RIGHT或FULL连接。测试将失败,因为预期的数据不会被退回。但它允许存储过程更改为此并仍然有效:
SELECT
A.Column1,
B.Column2
FROM TableA A, TableB B
WHERE A.Id = B.Id
这就是为什么我们不应该强制使用INNER JOIN,因为有很多其他有效的方法可以实现查询。