【问题标题】:Which is better, ExpectedException or @Test(expected= [closed]哪个更好,ExpectedException 或 @Test(expected= [关闭]
【发布时间】:2012-07-11 05:25:11
【问题描述】:

我有代码可以检查 jUnit 中的异常。我想知道以下哪一项是好的 jUnit 实践?

第一

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

@Test
public void checkNullObject() throws CustomException {
    exception.expect(CustomException.class);
    MyClass myClass= null;
    MyCustomClass.get(null);
}

第二

@Test(expected=CustomException.class)
public void checkNullObject() throws CustomException {
    MyClass myClass= null;
    MyCustomClass.get(null);    
}

编辑:请注意 CustomException 是未经检查的自定义异常。 (虽然不会对这个问题产生任何影响)。

【问题讨论】:

标签: java exception junit


【解决方案1】:

这取决于您要检查异常的内容。如果您所做的只是检查是否引发了异常,那么使用@Test(expected=...) 可能是最简单的方法:

@Test(expected=CustomException.class)
public void checkNullObject() throws CustomException {
  MyClass myClass= null;
  MyCustomClass.get(null);
}

但是,@Rule ExpectedException 有更多选项,包括检查消息,来自javadoc

// These tests all pass.
public static class HasExpectedException {
    @Rule
    public ExpectedException thrown= ExpectedException.none();

    @Test
    public void throwsNothing() {
        // no exception expected, none thrown: passes.
    }

    @Test
    public void throwsNullPointerException() {
        thrown.expect(NullPointerException.class);
        throw new NullPointerException();
    }

    @Test
    public void throwsNullPointerExceptionWithMessage() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage("happened?");
        thrown.expectMessage(startsWith("What"));
        throw new NullPointerException("What happened?");
    }

    @Test
    public void throwsIllegalArgumentExceptionWithMessageAndCause() {
        NullPointerException expectedCause = new NullPointerException();
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("What");
        thrown.expectCause(is(expectedCause));
        throw new IllegalArgumentException("What happened?", cause);
    }
}

因此您可以检查消息,即异常的原始原因。检查消息,你可以使用匹配器,所以你可以检查startsWith()和类似的。

使用旧式 (Junit 3) throw/catch 的一个原因是如果您有特定要求。这些并不多,但它可能会发生:

@Test
public void testMe() {
    try {
        Integer.parseInt("foobar");
        fail("expected Exception here");
    } catch (Exception e) {
        // OK
    }
}

【讨论】:

  • 仅供参考,javadoc 链接是 404
  • 使用@Test 来测试异常与@Rule ExpectedException 相比有两个缺点。 1.您不能断言原因/消息。例如@Nonnull 没有按预期工作,我们从其他地方获得了 NPE。 2. 当我们模拟异常时,@Test(expected) 会抛出异常日志,但如果异常匹配,@Rule 会吞下它们。
  • 只有旧样式才能确保在预期的地方抛出异常!
【解决方案2】:

第二个版本绝对是标准的做法。在 Junit 4 之前,老式的做法是这样的:

try {
    codeThatShouldThrowException();
    fail("should throw exception");
} catch (ExpectedException expected) {
    //Expected
}

有时您可能希望恢复到这种方式,例如,如果您想对异常中的消息进行断言。

【讨论】:

  • 我想即使我们想检查一些关于异常消息的东西,我们也可以使用this way。不需要使用这个 try -fail - catch 构造
  • 我特别说“在 Junit 4 之前”。 this way 不是指依赖于 @Rule 的解决方案,它是在 Juni 4 中引入的吗? testwithspring.com/lesson/introduction-to-junit-4-rules
猜你喜欢
  • 2011-03-19
  • 2011-01-05
  • 2010-11-24
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
相关资源
最近更新 更多