简体   繁体   English

JUnit 4预期的异常类型

[英]JUnit 4 Expected Exception type

I am trying to do a JUnit test on code that someone else has written, but I cannot figure out how to test for the exception, because the exception seems to lack a type. 我正在尝试对其他人编写的代码进行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;
}

My JUnit Code snippet: 我的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);

}

I know I need to put expected = (some type of exception) in the parenthesis of test, but I am clueless as to the exception type. 我知道我需要在测试的括号中放置expected =(某种类型的异常),但我对异常类型一无所知。

There's actually an alternative to the @Test(expected=Xyz.class) in JUnit 4.7 using Rule and ExpectedException 使用RuleExpectedException实际上是JUnit 4.7中@Test(expected=Xyz.class)的替代方法

In your test case you declare an ExpectedException annotated with @Rule , and assign it a default value of ExpectedException.none() . 在您的测试情况下,你声明ExpectedException带注释@Rule ,并指定其为默认值ExpectedException.none() Then in your test that expects an exception you replace the value with the actual expected value. 然后在您期望异常的测试中,将值替换为实际预期值。 The advantage of this is that without using the ugly try/catch method, you can further specify what the message within the exception was 这样做的好处是,如果不使用丑陋的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);
}

Using this method, you might be able to test for the message in the generic exception to be something specific. 使用此方法,您可能能够测试通用异常中的消息是否特定。

ADDITION Another advantage of using ExpectedException is that you can more precisely scope the exception within the context of the test case. 附加使用ExpectedException另一个好处是,您可以在测试用例的上下文中更精确地定义异常。 If you are only using @Test(expected=Xyz.class) annotation on the test, then the Xyz exception can be thrown anywhere in the test code -- including any test setup or pre-asserts within the test method. 如果您只在测试中使用@Test(expected=Xyz.class)注释,则可以在测试代码中的任何位置抛出@Test(expected=Xyz.class)异常 - 包括测试方法中的任何测试设置或预先断言。 This can lead to a false positive. 这可能导致误报。

Using ExpectedException, you can defer specifying the thrown.expect(Xyz.class) until after any setup and pre-asserts, just prior to actually invoking the method under test. 使用ExpectedException,您可以延迟指定thrown.expect(Xyz.class)直到任何设置和预先声明之后,就在实际调用测试方法之前。 Thus, you more accurately scope the exception to be thrown by the actual method invocation rather than any of the test fixture itself. 因此,您可以更准确地确定实际方法调用而不是任何测试夹具本身抛出的异常。

JUnit 5 NOTE: JUnit 5注意:

JUnit 5 JUnit Jupiter has removed @Test(expected=...) , @Rule and ExpectedException altogether. JUnit 5 JUnit Jupiter完全删除了@Test(expected=...)@RuleExpectedException They are replaced with the new assertThrows() , which requires the use of Java 8 and lambda syntax. 它们被新的assertThrows()取代,后者需要使用Java 8和lambda语法。 ExpectedException is still available for use in JUnit 5 through JUnit Vintage. ExpectedException仍然可以在JUnit 5到JUnit Vintage中使用。 Also JUnit Jupiter will also continue to support JUnit 4 ExpectedException through use of the junit-jupiter-migrationsupport module , but only if you add an additional class-level annotation of @EnableRuleMigrationSupport . 此外,JUnit Jupiter还将通过使用junit-jupiter-migrationsupport模块继续支持JUnit 4 ExpectedException ,但@EnableRuleMigrationSupport是您添加了@EnableRuleMigrationSupport的其他类级别注释。

You could either use expected in @Test annotation or provide an explicit catch block and issue a fail if the program flow is not as expected. 您可以在@Test注释中使用expected 提供显式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
    }
}

My personal preference is the first solution. 我个人的偏好是第一个解决方案。

You can use JUnit 'expected' to test exceptions: 您可以使用JUnit'expected'来测试异常:

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

After that it's up to you to throw that particular exception in your code. 之后,您可以在代码中抛出该特定异常。

I wouldn't throw an Exception if the gold isn't greater than or equal to zero. 如果黄金不大于或等于零,我不会抛出Exception I would throw an IllegalArgumentException . 我会抛出IllegalArgumentException It certainly sounds like it's illegal your Pirate to have a negative amount of gold. 这听起来像你的Pirate是非法的,以获得负金量。

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

Then in your JUnit test case, expect the IllegalArgumentException . 然后在您的JUnit测试用例中,期望IllegalArgumentException

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM