关于java:junit测试方法可以抛出异常吗?

Can junit test method throw an exception?

你能不能告诉我,通常的做法是编写一个名为JUnit Test的方法,例如抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
    public String f(int param) throws Exception {
        if (param == 100500)
            throw new Exception();
        return"";
    }
}

private A object = new A();

@Test
public void testSomething() throws Exception {
    String expected ="";
    assertEquals(object.f(5), expected);
}

实际上,方法f()不会为该参数抛出异常(5)但是我必须声明该异常。


是的,它是完全正常的,如果它确实抛出异常,测试将被视为失败。

您需要指定该方法抛出Exception,即使您知道特定情况不是(此检查由编译器完成)。

在这种情况下,您期望的是object.f(5)返回一个空字符串。任何其他结果(非空字符串或抛出异常)都会导致测试用例失败。


JUnit-Test旨在测试给定方法的正确行为。测试方法抛出错误(例如,错误的参数)是一个完全有效的方案。如果它是一个经过检查的异常,您必须将其添加到测试方法声明中或在方法中捕获它并将Assert设置为false(如果不应该发生异常)。

您可以使用@Test注释中的expected字段,告诉JUnit如果发生异常,该测试应该通过。

1
2
3
4
5
@Test(expected = Exception.class)
public void testSomething() throws Exception {
    String expected ="";
    assertEquals(object.f(5), expected);
}

在这种情况下,测试方法应抛出异常,因此测试将通过。如果从注释中删除expected = Exception.class,则在发生异常时测试将失败。


如果您正在调用的方法抛出一个已检查的异常,则您需要尝试catch或重新抛出。从测试本身做到这一点很好。有多种方法可以使用JUnit测试Exception。我试着在下面提供一个简短的摘要:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

/**
 * Example uses Kent Beck - Test Driven Development style test naming
 * conventions
 */

public class StackOverflowExample {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    // Note the checked exception makes us re-throw or try / catch (we're
    // re-throwing in this case)
    public void calling_a_method_which_throws_a_checked_exception_which_wont_be_thrown() throws Exception {
        throwCheckedException(false);
    }

    /*
     * Put the class of the specific Exception you're looking to trigger in the
     * annotation below. Note the test would fail if it weren't for the expected
     * annotation.
     */

    @Test(expected = Exception.class)
    public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type()
            throws Exception {
        throwCheckedException(true);
    }

    /*
     * Using ExpectedException we can also test for the message. This is my
     * preferred method.
     */

    @Test
    public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type_and_message()
            throws Exception {
        expectedException.expect(Exception.class);
        expectedException.expectMessage("Stack overflow example: checkedExceptionThrower");
        throwCheckedException(true);
    }

    // Note we don't need to rethrow, or try / catch as the Exception is
    // unchecked.
    @Test
    public void calling_a_method_which_throws_an_unchecked_exception() {
        expectedException.expect(Exception.class);
        expectedException.expectMessage("Stack overflow example: uncheckedExceptionThrower");
        throwUncheckedException();
    }

    private void throwCheckedException(boolean willThrow) throws Exception {
        // Exception is a checked Exception
        if (willThrow) {
            throw new Exception("Stack overflow example: checkedExceptionThrower");
        }
    }

    private void throwUncheckedException() throws NullPointerException {
        // NullPointerException is an unchecked Exception
        throw new NullPointerException("Stack overflow example: uncheckedExceptionThrower");
    }

}


您可以使用以下命令测试是否启动了异常:

1
2
3
4
@Test(expected = ValidationException.class)
public void testGreaterEqual() throws ValidationException {
    Validate.greaterEqual(new Float(-5), 0f,"error7");
}