有没有办法在调用tSQLt.ExpectException后测试测试中的其他断言?

时间:2016-08-09 14:04:13

标签: tsqlt

使用tSQLt 1.0.5873.27393,我试图为存储过程编写一个tSQLt测试,在将错误重新抛出到调用会话之前将记录在CATCH块中的错误记录到日志表中

我可以成功测试使用tSQLt.ExpectException重新抛出错误消息,但副作用似乎是在调用tSQLt.ExpectException后无法测试任何其他断言 - 所以我无法测试错误是否已写入日志表。

我能提出的最简单的测试证明了这个问题:

CREATE PROC MyTests.[test ExpectException]
AS
BEGIN
    EXEC tSQLt.ExpectException;
    THROW 50001, 'Error message',1

    EXEC tSQLt.AssertEquals 0,1, '0=1'
END
GO

在执行时产生以下(意外)输出:

|No|Test Case Name                  |Dur(ms)|Result |
+--+--------------------------------+-------+-------+
|1 |[MyTests].[test ExpectException]|      3|Success|

使用分析器跟踪,我可以看到AssertEquals断言永远不会被执行,因为错误被CATCH内的tSQLt.Private_RunTest块捕获。

因为tSQLt使用CATCH来捕获错误,所以我怀疑在没有重大改写tSQLt的情况下没有解决这个问题的方法 - 但是我在这里问以防万一其他人找到解决问题的方法

3 个答案:

答案 0 :(得分:3)

您可以采用以下方法:

在测试中,将您的调用包装在try / catch块中的测试存储过程中。 在try / catch块之前,将预期变量设置为1,将实际设置为0。 在测试catch块中,检查日志表是否已填充,如果是,则将实际变量翻转为1。 在catch块之后写下你的断言。

CREATE PROC MyTests.[test ExpectException]
AS
    BEGIN
    DECLARE @expected bit = 1;
    DECLARE @actual bit = 0;

    BEGIN TRY
        -- call tested SP, make sure it fails
        CALL SP..;

        -- add safety net, if the SP call doesn't fail then fail the test
        RAISERROR('Fail the test', 16, 1);
    END TRY
    BEGIN CATCH
        -- pseudo code
        IF EXISTS (SELECT 1 FROM log table)
        -> flip @actual to 1
    END CATCH

    EXEC tSQLt.AssertEquals @expected, @actual
END
GO

答案 1 :(得分:0)

@Eduard Uta在我做之前到过那里,但无论如何我都会发布。

我几乎在发布此消息时就明白了,明显的解决方案是使用自定义TRY...CATCH块,而不是使用内置的tSQLt对象:

CREATE PROC MyTests.[test custom try catch]
AS
BEGIN
    DECLARE @ErrorRaised bit = 0

    BEGIN TRY
        THROW 50001, 'Error message',1
    END TRY
    BEGIN CATCH
        SET @ErrorRaised = 1
    END CATCH

    EXEC tSQLt.AssertEquals 1,@ErrorRaised, 'Error raised'

    EXEC tSQLt.AssertEquals 0,1, '0=1'
END
GO

以下是测试特定错误消息的示例:

CREATE PROC MyTests.[test custom try catch test message]
AS
BEGIN
    DECLARE @ErrorRaised bit = 0

    BEGIN TRY
        THROW 50001, 'Error message',1
    END TRY
    BEGIN CATCH
        IF ERROR_MESSAGE() = 'Error message'
            SET @ErrorRaised = 1
        ELSE
            THROW
    END CATCH

    EXEC tSQLt.AssertEquals 1,@ErrorRaised, 'Error raised'

    EXEC tSQLt.AssertEquals 0,1, '0=1'
END
GO

答案 2 :(得分:0)

对我来说,在 TRY...CATCH 块中调用被测过程和 tSQLt ExpectException 过程似乎已经成功。

CREATE PROC MyTests.[test ExpectException]
AS
BEGIN
  BEGIN TRY
    -- Call the proc that raises the error
    EXEC offending_stored_proc

    -- Tell tSQLt to expect the exception
    EXEC tSQLt.ExpectException @ExpectedMessage = 'Expected error message', @ExpectedSeverity = NULL, @ExpectedState = NULL;
  END TRY
  BEGIN CATCH
    -- No need to do anything here
  END CATCH
END;

正如预期的那样,如果过程引发带有该错误消息的错误,则测试通过。如果未引发错误,则测试失败。