From: Thomas M. <tho...@gm...> - 2011-07-07 20:10:31
|
Hi, I have many test cases that expect an exception to be thrown. I want to verify that a given method of my code will actually throw an exception in a given test case. What I want is described here: http://stackoverflow.com/questions/156503/how-to-assert-that-a-certain-exception-is-thrown-in-junit4-5-tests - Example (please not my actual use case isn't ArrayList - this is just an example): List<String> myObject = new ArrayList<String>(); // current pattern - 6 lines of code try { myObject.get(0); fail(); } catch (IndexOutOfBoundsException e) { // expected } Now, I have a few problems with this. First, it's 6 lines of code, which is a lot. Then, it's too easy to forget 'fail()' (I forgot it in many cases). I know I could refactor the test to move it to a separate method, and add @Test(expected=IndexOutOfBoundsException.class) (the top answer on StackOverflow) - but that's ugly as well. I don't _want_ a separate test method. I found a solution to simplify the test, by creating a new helper method 'assertThrows' (implementation below), so that my test case is now: // shorter, 1 line assertThrows(IndexOutOfBoundsException.class, myObject).get(0); // even shorter (if I don't care what kind of exception) assertThrows(myObject).get(0); My solution currently uses a Java proxy (which obviously only works for interfaces), but using CGLIB it would be possible to support (non-final) regular classes as well. Anyway, for reference, my solution is here: http://h2database.com/p.html#554bf1f041969cba0f6fa1a6e8e20cba - my solution checks that a method was called by miss-using finalize, which is OK for my use case (there are probably better solutions for this). I know there are other solutions. I do know this has been discussed before on the JUnit list: http://old.nabble.com/assertNotEquals-and-assertThrows-td3423551.html I also know that JUnit 4.7+ has "Rules" but I really don't want to write one method for each test. It's ugly because it forces me to split a test into many tiny methods. I don't like this. For example, I have test code like this: assertThrows(stat).execute("select sum(id) from test for update"); assertThrows(stat).execute("select distinct id from test for update"); assertThrows(stat).execute("select id from test group by id for update"); assertThrows(stat).execute("select t1.id from test t1, test t2 for update"); Every *line* would have to be in it's own method. I have the feeling my feature request will reject it because it would force JUnit to include a proxy mechanism like CGLIB (which I guess isn't included now; maybe I'm wrong). And you will probably it's a bit hacky (well, it is). But it *is* very useful (at least in my view). I have already submitted this request to Mockito, but they are not interested that much - they wrote this feature is something that JUnit is supposed support, as it's not that much related to what Mockito does. So, what do you think? Regards, Thomas |