我正在尝试对其他人编写的代码进行JUnit测试,但是我无法弄清楚如何测试该异常,因为该异常似乎缺少类型。
public Pirate(String name, int initialGold) throws Exception { if(initialGold < 0) throw new Exception("Init Gold must be >= 0"); this.name = name; this.numGold = initialGold; this.health = Pirate.DEFAULT_HEALTH; this.isCursed = false; }
我的JUnit代码段:
@Test public static void constructorTest() throws Exception{ rodgers = new Pirate("Dread Pirate Rodgers", 10000); assertEquals("Dread Pirate Rodgers" , rodgers.getName()); assertEquals(10000, rodgers.getNumGold()); assertEquals(100, rodgers.getHealth()); assertEquals(false, rodgers.getIsCursed()); } @Test() public static void exceptionTest() throws Exception{ rodgers = new Pirate("Dread Pirate Rodgers" , -100); }
我知道我需要在测试的括号中加上期望的=(某种异常类型),但是对于异常类型我一无所知。
实际上,@Test(expected=Xyz.class)在JUnit 4.7中有一个替代方法是使用Rule和ExpectedException
@Test(expected=Xyz.class)
Rule
ExpectedException
在测试用例中,您声明ExpectedException带有@Rule,并为其指定默认值ExpectedException.none()。然后,在预期异常的测试中,将值替换为实际预期值。这样做的好处是,无需使用难看的try / catch方法,您就可以进一步指定异常中的消息是
@Rule
ExpectedException.none()
@Rule public ExpectedException thrown= ExpectedException.none(); @Test public void myTest() { thrown.expect( Exception.class ); thrown.expectMessage("Init Gold must be >= 0"); rodgers = new Pirate("Dread Pirate Rodgers" , -100); }
使用此方法,您可能能够在通用异常中测试消息是否是特定的。
附加使用的 另一个优点ExpectedException是,您可以在测试用例的上下文中更精确地确定异常的范围。如果仅@Test(expected=Xyz.class)在测试中使用批注,则可以在测试代码中的任何位置引发Xyz异常- 包括测试方法中的任何测试设置或预声明。这可能导致误报。
使用ExpectedException,您可以推迟指定,thrown.expect(Xyz.class)直到在任何设置和预声明之后才实际调用被测方法之前。因此,您可以更准确地确定实际方法调用而不是测试夹具本身抛出的异常的范围。
thrown.expect(Xyz.class)
JUnit 5注:
的JUnit 5的JUnit木星除去@Test(expected=...),@Rule和ExpectedException完全。它们被new替换assertThrows(),这需要使用Java 8和lambda语法。 ExpectedException仍可通过JUnit Vintage在JUnit 5中使用。此外,JUnit Jupiter也将ExpectedException通过使用junit-jupiter- migrationsupport模块继续支持JUnit 4 ,但前提是您添加了附加的类级注释@EnableRuleMigrationSupport。
@Test(expected=...)
assertThrows()
@EnableRuleMigrationSupport