tSQLt简单的SELECT语句 - 我需要哪些测试?最佳实践

时间:2015-10-13 08:37:53

标签: sql-server tsql tsqlt

这是关于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语句进行可怕的测试。

我很感激社区的想法。

谢谢,

1 个答案:

答案 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,因为有很多其他有效的方法可以实现查询。