JUnit Exception Testing
编辑:目前不提供JUnit 4。
嗨,您好,
我有一个关于使用JUnit进行"智能"异常测试的问题。 这时,我这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public void testGet() { SoundFileManager sfm = new SoundFileManager(); // Test adding a sound file and then getting it by id and name. try { SoundFile addedFile = sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); SoundFile sf = sfm.getSoundfile(addedFile.getID()); assertTrue(sf!=null); System.out.println(sf.toString()); sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); assertTrue(sf!=null); System.out.println(sf.toString()); } catch (RapsManagerException e) { System.out.println(e.getMessage()); } // Test get with invalid id. try { sfm.getSoundfile(-100); fail("Should have raised a RapsManagerException"); } catch (RapsManagerException e) { System.out.println(e.getMessage()); } // Test get by name with invalid name try { sfm.getSoundfileByName(new String()); fail("Should have raised a RapsManagerException"); } catch (RapsManagerException e) { System.out.println(e.getMessage()); } } |
正如您所看到的,我需要为每个应该抛出异常的函数提供一个try / catch块。 这似乎不是一个好方法 - 或者是否有可能减少try / catch的使用?
我建议您需要将
完成后,您可以使用JUnit4的异常注释支持,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public class MyTest { private SoundManager sfm; @Before public void setup() { sfm = new SoundFileManager(); } @Test public void getByIdAndName() { // Test adding a sound file and then getting it by id and name. SoundFile addedFile = sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); SoundFile sf = sfm.getSoundfile(addedFile.getID()); assertTrue(sf!=null); System.out.println(sf.toString()); sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); assertTrue(sf!=null); System.out.println(sf.toString()); } @Test(expected=RapsManagerException.class) public void getByInvalidId() { // Test get with invalid id. sfm.getSoundfile(-100); } @Test(expected=RapsManagerException.class) public void getByInvalidName() { // Test get with invalid id. sfm.getSoundfileByName(new String()); } } |
如果你有一个预期的异常并且你不能使用注释来捕获它,你需要捕获它并断言你已经得到了你所期望的。例如:
1 2 3 4 5 6 7 8 |
如果您可以使用注释,请执行此操作,因为它更清晰。但这并不总是可行的(例如,因为您正在测试一系列方法或因为您正在使用JUnit 3)。
使用JUnit 4,您可以使用注释。但是,您应该将测试分为3种不同的方法,以便干净地工作。请注意,在第一个场景中捕获异常的IMHO应该是失败的,因此我相应地修改了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public void testGet() { SoundFileManager sfm = new SoundFileManager(); // Test adding a sound file and then getting it by id and name. try { SoundFile addedFile = sfm.addSoundfile("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); SoundFile sf = sfm.getSoundfile(addedFile.getID()); assertTrue(sf!=null); System.out.println(sf.toString()); sf = sfm.getSoundfileByName("E:\\Eclipse_Prj\\pSound\\data\\Adrenaline01.wav"); assertTrue(sf!=null); System.out.println(sf.toString()); } catch (RapsManagerException e) { fail(e.getMessage()); } } @Test(expected=RapsManagerException.class) public void testGetWithInvalidId() { SoundFileManager sfm = new SoundFileManager(); sfm.getSoundfile(-100); } @Test(expected=RapsManagerException.class) public void testGetWithInvalidName() { SoundFileManager sfm = new SoundFileManager(); sfm.getSoundfileByName(new String()); } |
catch-exception提供了最简洁的语法:
1 2 3 4 5 6 7 8 9 10 | public void testGet() { SoundFileManager sfm = new SoundFileManager(); ... // setup sound file manager verifyException(sfm, RapsManagerException.class) .getSoundfile(-100); verifyException(sfm, RapsManagerException.class) .getSoundfileByName(new String()); } |
在Java 8中,您可以使用lambda表达式来更严格地控??制何时抛出异常。如果您使用注释方法,那么您只是断言在测试方法中的某处抛出了异常。如果您在测试中执行了多行代码,那么当测试失败时,您将面临测试通过的风险。 Java 8解决方案就是这样的。
1 2 3 4 5 6 7 8 9 |
用法:
1 2 3 4 5 6 | @Test public void test() MyClass foo = new MyClass(); // other setup code here .... expectException(MyException.class, () -> foo.bar()); } |