From: Thomas M. <tho...@gm...> - 2011-07-08 09:26:03
|
Hi, > No, we're unlikely to include it in base JUnit, because the reflection > magic is likely to not work on all platforms that JUnit currently > works on, and, as you point out, it won't work on final classes, or > any classes without CGLIB, etc. I understand. Well, java.lang.reflect.Proxy is supposed to run everywhere, but it does make sense to try it out in an experimental project. > However, it's an absolutely perfect idea for junit.contrib, the > companion project for experimental code, which I'm trying to get off > the ground. The submission process to junit.contrib is still > relatively undefined (which is why there's no code there yet). Would > you be interested in being a charter contributor? Sure. You need to tell me what the directory structure and so on is supposed to look like. I can write a patch for assertThrows as it is now (to support interfaces only; without any bytecode manipulation), together with some documentation. That alone solves 90% of the problem. Non-interface methods will require more work. I'm not sure if it makes sense to "role your own" bytecode generation, or depend one of the existing libraries (bcel, asm, cglib). It sounds like what assertThrows needs is a small subset of what those tool can do. I do have a little bit of experience with bytecode (re-construct the source code from the bytecode for my JaQu tool - http://www.h2database.com/html/jaqu.html) and will try, but I can't promise much. With this, you are at 98%. Still remaining are static methods and final classes. This is even more complicated, but maybe there is a way - see http://code.google.com/p/powermock/ and http://projectlombok.org/ To make the method sound less weird, I would document it as follows: Object assertThrows(Object o) Creates a verifying proxy for an object, which checks each method call throws an exception. Example: // Wrap the object into a proxy List proxyList = assertThrows(myList); // This will internally call myList.get(0) and verify it throws an exception. // If it doesn't throw an exception, then the proxy calls Assert.fail(). proxyList.get(0); // Simplified usage assertThrows(myList).get(0); -------------------- Then, what about: // check the method call is relatively fast / slow assertFast([maxMillis,] myObject).myMethod() assertSlow([maxMillis,] myObject).myMethod() I don't have a use case for those, but probably others. // call the method in a loop (with a 10 ms delay) until it returns the expected result assertEventuallyTrue([maxMillis,] myObject).myMethod() assertEventuallyFalse([maxMillis,] myObject).myMethod() I do have an actual use case for assertEventuallyTrue/False: my program is supposed to delete files in a background thread within some non-deterministic time. And I don't want to use Thread.sleep(..) because it slows down testing unnecessarily (usually, the thread is quick). Regards, Thomas |