Friday, 15 March 2013

vba - Expected error can only be a 440/Automation Error? -



vba - Expected error can only be a 440/Automation Error? -

context

i have written little unit testing library in vba, can write unit tests this:

'@expectederror() public sub testcannotregisterloggertwice() dim logger ilogger set logger = mocklogger.create("testlogger", tracelevel) logmanager.register logger logmanager.register logger end sub

the above test passes:

class="lang-none prettyprint-override">2014-10-04 16:42:55 testcannotregisterloggertwice: [pass]

and if remove expectederror "attribute", fails:

class="lang-none prettyprint-override">2014-10-04 16:43:49 testcannotregisterloggertwice: [inconclusive] - test raised error: automation error

so far, good. well, almost.

in-test errors work fine!

now if create test throw division zero, this:

'@expectederror() public sub testcannotregisterloggertwice() dim logger ilogger set logger = mocklogger.create("testlogger", tracelevel) dim boom integer boom = 1 / 0 logmanager.register logger logmanager.register logger end sub

the test still inconclusive, time error correctly picked up:

class="lang-none prettyprint-override">2014-10-04 16:45:12 testcannotregisterloggertwice: [inconclusive] - test raised error: partition 0

the part don't understand, in both cases, error raised in same vbaproject - former in class called logmanager (the sut), latter in class called logmanagertests.

here part throws expected error i'm testing for:

public sub register(byval logger ilogger) if not this.loggers.exists(logger.name) this.loggers.add logger.name, logger else err.raise logmanagererror.duplicateloggererror, "logmanager.register", "there logger registered name '" & logger.name & "'." end if end sub what want

i able decorate test methods '@expectederror(-2147220406) (the long representation of logmanagererror.duplicateloggererror), , able clean part up, in testengine.reflecttestmethods method:

for each prospect in classmethods if canaddtestmethod(prospect, result) set tmethod = new testmethod set tmethod.ownerinstance = classinstance tmethod.methodname = prospect.name if prospect.hasattribute(expectederrorattribute) if prospect.attributeparameters(expectederrorattribute).count <> 0 err.raise vbobjecterror + 1055, "testengine.reflecttestmethods", "expectederrorattribute test method '" & prospect.name & "' should not have parameters." end if 'force "automation error" expected, 'because vba "eats" expected error thrown in sut: tmethod.expectederror = 440 ' prospect.attributeparameters(expectederrorattribute).first end if result.add tmethod.methodname, tmethod end if next

is so? can ever expect sut throw automation error?

something i've tried

since error correctly reported when it's thrown in actual test method, tried this:

'@expectederror() public sub testcannotregisterloggertwice() on error goto cleanfail dim logger ilogger set logger = mocklogger.create("testlogger", tracelevel) logmanager.register logger logmanager.register logger exit sub cleanfail: dim errnumber long errnumber = err.number dim errsource string errsource = err.source dim errdescription string errdescription = err.description err.raise errnumber, errsource, errdescription end sub

but though errdescription contains correct/expected error message, testing library still receives automation error number 440.

why testing library correctly pick partition zero, not custom error?

edit: upon farther experimentation, noticed can "expect" built-in error, works:

'@expectederror(5) public sub testcannotregisterloggertwice() dim logger ilogger set logger = mocklogger.create("testlogger", tracelevel) logmanager.register logger logmanager.register logger end sub

...provided alter testengine code take parameters @expectederror attribute, , raise error #5 / "invalid procedure phone call or argument" in sut, instead of custom error; can't provide custom error message either. isn't ideal, because forces sut throw built-in errors, , testing library can't assume it's case.

what's special custom error codes in vba?

i don't know what's special custom error codes in vba.

but if error numbers thrown in sut not in form of recommended vbobjecterror + n (as can inferred -2147220406 representation of error code you're expecting), application-defined or object-defined error can used, , "expected":

public enum logmanagererror duplicateloggererror = 100 loggernotregisterederror end enum

the testengine still not "see" custom error message, can this:

'@expectederror(100) public sub testcannotregisterloggertwice() dim logger ilogger set logger = mocklogger.create("testlogger", tracelevel) logmanager.register logger logmanager.register logger end sub

and result:

class="lang-none prettyprint-override">2014-10-04 18:09:56 testcannotregisterloggertwice: [pass]

if expectederror attribute removed, application-defined or object-defined error:

class="lang-none prettyprint-override">2014-10-04 18:10:20 testcannotregisterloggertwice: [inconclusive] - test raised error: application-defined or object-defined error

which technically right - granted, nice able study custom error message in test result, it's 1 of limitations have dealt with.

at to the lowest degree can throw different errors in sut, and able tell whether that error raised - goal achieved here.

meanwhile custom error message still visible , displayable in "normal" code:

'@expectederror(100) public sub testcannotregisterloggertwice() on error goto cleanfail dim logger 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

class="lang-none prettyprint-override">2014-10-04 18:21:24 testcannotregisterloggertwice: [pass]

vba unit-testing error-handling

No comments:

Post a Comment