预期的错误只能是440 /自动化错误?

时间:2014-10-04 21:09:46

标签: vba unit-testing error-handling

上下文

我在VBA中写了一点unit testing library,所以我可以写这样的单元测试:

'@ExpectedError()
Public Sub TestCannotRegisterLoggerTwice()

    Dim logger As ILogger
    Set logger = MockLogger.Create("TestLogger", TraceLevel)

    LogManager.Register logger
    LogManager.Register logger

End Sub

以上测试通过:

2014-10-04 16:42:55 TestCannotRegisterLoggerTwice: [PASS]

如果我删除了ExpectedError“属性”,则会失败:

2014-10-04 16:43:49 TestCannotRegisterLoggerTwice: [INCONCLUSIVE] - Test raised an error: Automation error

到目前为止,这么好。好吧,差不多。


测试中错误工作正常!

现在,如果我让测试将除以零,则像这样:

'@ExpectedError()
Public Sub TestCannotRegisterLoggerTwice()

    Dim logger As ILogger
    Set logger = MockLogger.Create("TestLogger", TraceLevel)

    Dim boom As Integer
    boom = 1 / 0

    LogManager.Register logger
    LogManager.Register logger

End Sub

测试仍然没有结果,但这次错误被正确选取:

2014-10-04 16:45:12 TestCannotRegisterLoggerTwice: [INCONCLUSIVE] - Test raised an error: Division by zero

我不明白的部分是,在两种情况下,错误都是在同一个VBAProject中引发 - 前者在一个名为LogManager的类中(SUT),后者在一个名为LogManagerTests的课程中。

以下是抛出我正在测试的预期错误的部分:

Public Sub Register(ByVal logger As ILogger)
    If Not this.Loggers.Exists(logger.Name) Then
        this.Loggers.Add logger.Name, logger
    Else
        Err.Raise LogManagerError.DuplicateLoggerError, "LogManager.Register", "There is already a logger registered with name '" & logger.Name & "'."
    End If
End Sub

我想要什么

我希望能够使用'@ExpectedError(-2147220406)Long LogManagerError.DuplicateLoggerError表示法)来装饰我的测试方法,并且能够在{{{{{}}中清除此部分。 1}}方法:

TestEngine.ReflectTestMethods
是吗?是这样吗?我只能指望SUT抛出自动化错误


我试过的东西

由于在实际测试方法中抛出错误时会正确报告错误,我试过这个:

For Each prospect In classMethods

    If CanAddTestMethod(prospect, result) Then

        Set tMethod = New TestMethod
        Set tMethod.OwnerInstance = classInstance
        tMethod.MethodName = prospect.name

        If prospect.HasAttribute(ExpectedErrorAttribute) Then
            If prospect.AttributeParameters(ExpectedErrorAttribute).Count <> 0 Then
                Err.Raise vbObjectError + 1055, "TestEngine.ReflectTestMethods", "ExpectedErrorAttribute for test method '" & prospect.name & "' should not have parameters."
            End If

            'force an "Automation Error" to be expected, 
            'because VBA "eats" the expected error thrown in the SUT:
            tMethod.ExpectedError = 440 ' prospect.AttributeParameters(ExpectedErrorAttribute).First

        End If

        result.Add tMethod.MethodName, tMethod

    End If

Next

但即使'@ExpectedError() Public Sub TestCannotRegisterLoggerTwice() On Error GoTo CleanFail Dim logger As ILogger Set logger = MockLogger.Create("TestLogger", TraceLevel) LogManager.Register logger LogManager.Register logger Exit Sub CleanFail: Dim errNumber As Long errNumber = Err.Number Dim errSource As String errSource = Err.Source Dim errDescription As String errDescription = Err.Description Err.Raise errNumber, errSource, errDescription End Sub 包含正确/预期的错误消息,测试库仍会收到编号为440的自动化错误


为什么我的测试库正确地将除法除以零,而不是自定义错误?

编辑:经过进一步的实验,我注意到我可以成功“预期”任何内置错误,所以这有效:

errDescription

...如果更改我的'@ExpectedError(5) Public Sub TestCannotRegisterLoggerTwice() Dim logger As ILogger Set logger = MockLogger.Create("TestLogger", TraceLevel) LogManager.Register logger LogManager.Register logger End Sub 代码以接受TestEngine属性的参数,并且我在SUT中引发错误#5 /“无效的过程调用或参数”,而不是自定义错误;我也无法提供自定义错误消息。这并不理想,因为它强制SUT只抛出内置错误,而我的测试库不能认为是这种情况。

VBA中的自定义错误代码有什么特别之处?

1 个答案:

答案 0 :(得分:2)

我不知道VBA中有关自定义错误代码的特殊之处。

但是如果SUT中抛出的错误编号是,则推荐vbObjectError + n的形式(可以从错误代码的-2147220406表示中推断出你& #39; re expecting),然后可以使用任何应用程序定义的或对象定义的错误,并且&#34;期望&#34;:

Public Enum LogManagerError
    DuplicateLoggerError = 100
    LoggerNotRegisteredError
End Enum

TestEngine仍然没有&#34;看到&#34;自定义错误消息,但现在您可以执行此操作:

'@ExpectedError(100)
Public Sub TestCannotRegisterLoggerTwice()

    Dim logger As ILogger
    Set logger = MockLogger.Create("TestLogger", TraceLevel)

    LogManager.Register logger
    LogManager.Register logger

End Sub

得到这个结果:

2014-10-04 18:09:56 TestCannotRegisterLoggerTwice: [PASS]

如果删除了ExpectedError属性,则会出现应用程序定义的错误或对象定义错误

2014-10-04 18:10:20 TestCannotRegisterLoggerTwice: [INCONCLUSIVE] - Test raised an error: Application-defined or object-defined error

技术上是正确的 - 授予,能够在测试结果中报告自定义错误消息会很好,但它只是必须处理的那些限制之一。

至少你现在可以在SUT中抛出不同的错误,并能够判断 错误是否被引发 - 这是在这里实现的目标。< / p>

同时,自定义错误消息仍然可见并且可以显示在&#34; normal&#34;代码:

'@ExpectedError(100)
Public Sub TestCannotRegisterLoggerTwice()

    On Error GoTo CleanFail

    Dim logger As ILogger
    Set logger = MockLogger.Create("TestLogger", TraceLevel)

    LogManager.Register logger
    LogManager.Register logger

    Exit Sub
CleanFail:
    MsgBox Err.Description
    Err.Raise Err.Number

End Sub

"There is already a logger registered with the name 'TestLogger'."

2014-10-04 18:21:24 TestCannotRegisterLoggerTwice: [PASS]