使用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的情况下没有解决这个问题的方法 - 但是我在这里问以防万一其他人找到解决问题的方法
答案 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;
正如预期的那样,如果过程引发带有该错误消息的错误,则测试通过。如果未引发错误,则测试失败。