JUnit 4预期的异常类型

时间:2013-05-23 20:54:51

标签: java object testing junit

我正在尝试对其他人编写的代码进行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);

}

我知道我需要在测试的括号中放置expected =(某种类型的异常),但我对异常类型一无所知。

4 个答案:

答案 0 :(得分:106)

使用RuleExpectedException

实际上是JUnit 4.7中@Test(expected=Xyz.class)的替代方案

在您的测试用例中,您声明了ExpectedException注释了@Rule,并为其指定了默认值ExpectedException.none()。然后在您期望异常的测试中,将值替换为实际预期值。这样做的好处是,如果不使用丑陋的try / catch方法,您可以进一步指定异常中的消息是什么

@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);
}

使用此方法,您可以测试通用异常中的消息是否特定。

<强> ADDITION 使用ExpectedException的另一个好处是,您可以在测试用例的上下文中更精确地定义异常。如果您只在测试中使用@Test(expected=Xyz.class)注释,则可以在测试代码中的任何位置抛出Xyz异常 - 包括测试方法中的任何测试设置或预先断言。这可能会导致误报。

使用ExpectedException,您可以在实际调用测试方法之前,在任何设置和预先声明之后推迟指定thrown.expect(Xyz.class)。因此,您可以更准确地确定实际方法调用而不是任何测试夹具本身抛出的异常范围。

JUnit 5注意:

JUnit 5 JUnit Jupiter完全删除了@Test(expected=...)@RuleExpectedException。它们被新的assertThrows()取代,后者需要使用Java 8和lambda语法。 {JENit Vintage仍然可以在JUnit 5中使用ExpectedException。此外,JUnit Jupiter还将继续使用junit-jupiter-migrationsupport module来支持JUnit 4 ExpectedException,但前提是您添加了@EnableRuleMigrationSupport的其他类级别注释。

答案 1 :(得分:20)

您可以在 @Test 注释中使用预期 提供明确的catch块并发出失败如果程序流程不符合预期。

@Test(expected=Exception.class) // java.lang.Exception
public static void exceptionTest() throws Exception {
    rodgers = new Pirate("Dread Pirate Rodgers" , -100);
}

@Test
public static void exceptionTest() throws Exception {
    try {
        rodgers = new Pirate("Dread Pirate Rodgers" , -100);
        fail("should not reach this");
    } catch(Exception e) {
        // ok
    }
}

我个人的偏好是第一个解决方案。

答案 2 :(得分:9)

您可以使用JUnit'expected'来测试异常:

@Test(expected = ExceptionYouWishToTestFor.class)  
public void divisionWithException() {  
    // Test Code
}

之后,您可以在代码中抛出该特定异常。

答案 3 :(得分:7)

如果黄金不大于或等于零,我不会抛出Exception。我会扔IllegalArgumentException。当然,你的Pirate贵金属是非法的。

public Pirate(String name, int initialGold) {
    if(initialGold < 0)
        throw new IllegalArgumentException("Init Gold must be >= 0");

然后在您的JUnit测试用例中,期待IllegalArgumentException

@Test(expected=IllegalArgumentException.class)
public static void exceptionTest() {