Junit在等待并处理异常后声明某些内容 [英] Junit assert something after awaiting and handling an exception

查看:142
本文介绍了Junit在等待并处理异常后声明某些内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在第一次调用和第二次调用时抛出的方法:

method which throws at first and second call:

public void foo() throws Exception

测试:

@test
public void testFooThrowsAtFirstAndSecondTime(){
    boolean thrown;
    try {
       foo();
    } catch (Exception e) {
       thrown = true;
    }
    assertTrue(thrown);

    thrown = false;
    try {
       foo();
    } catch (Exception e) {
       thrown = true;
    }
    assertTrue(thrown);

    foo();
}

您能帮我找到一个更好的解决方案吗? 使用Mockito以获得更好的解决方案也是可以接受的.

Could you help me find a better solution for this? Use of Mockito for a better solution would be also acceptable.

更好的意思是,如果我可以在测试中避免尝试/捕获,甚至避免多次尝试/捕获.在其他语言或jAssert中,我认为即使在春季,也有类似的语句:

With better i mean, if i could avoid try/catch or even multiple try/catch in my test. In other languages or in jAssert i think even in spring there are statements like:

assertThrows(method(..)) //PseudoCode

我认为与Mockito或JUnit 4.x相似.

I thought with Mockito or JUnit 4.x there is a similar thing.

我知道

@Test(expected=Exception)

但是,只有当我期望一掷并且测试在那之后结束时,这才是可以接受的.

But this would only be acceptable if i expect one throw and the test ends after that.

推荐答案

此处的关键是 try块至关重要 ,如果您想在发生异常后恢复执行.您可以将其分解为方法或库,但必须在测试方法中调用它.

The key here is that the try block is crucial if you want to resume execution after an exception. You can factor it out into a method or library, but it has to be called within your test method.

有效的方法:

  • The tried-and-true fail() idiom that you and nrainier cite, which I prefer:

try {
  foo();
  fail("foo did not throw an exception");
} catch (Exception ex) { } 

  • catch-exception 是一个像Mockito一样包装通过的库对象,并在每个方法周围放置一个try块. Mockito关于最终方法和类的警告在这里也适用,因此这并不总是有效.

  • catch-exception is a library that, like Mockito, wraps the passed object and puts a try block around each method. Mockito's caveats about final methods and classes apply here too, so this won't always work.

    List myList = new ArrayList();
    catchException(myList).get(1);  // myList is wrapped here
    assert caughtException() instanceof IndexOutOfBoundsException;
    

    请注意,catch-exception处于维护模式".因为Java 8解决方案(如下)更加可靠.

    Note that catch-exception is in "maintenance mode" because the Java 8 solution (below) is much more solid.

    任何解决方案,例如assertThrows(() -> methodThatThrows())(Java 8)或:

    Any solution like assertThrows(() -> methodThatThrows()) (Java 8) or:

    assertThrows(new Runnable() {
      @Override public void run() { methodThatThrows(); }
    });
    

    ...在Java 6/7中.重要的是, assertThrows在methodThatThrows 之前被调用,因此它可以调用methodThatThrows.感谢Stefan的指出鱼缸,但您可以自己编写一个等效的文字:

    ...in Java 6/7. Importantly, assertThrows is called before methodThatThrows, so it can invoke methodThatThrows. Thanks Stefan for pointing out Fishbowl, but you could easily write an equivalent yourself:

    public void assertThrows(Runnable block) {
      try {
        block.run();
        fail("Block didn't throw.");
      } catch (Exception ex) { }
    }
    

  • 不起作用的东西:

    • @Test(expected=YourException.class)将堆栈上移到JUnit将测试方法包装到的try块中.控制权在此之后再也不会返回到该测试方法.

    • @Test(expected=YourException.class) will go up the stack to the try block that JUnit wraps your test method in. Control never returns to the test method after that.

    JUnit4的ExpectedException @Rule看起来很吸引人,但是由于它包装了整个测试方法,因此您必须在调用引发异常的方法之前设置期望值.

    JUnit4's ExpectedException @Rule looks tempting, but because it wraps the entire test method, you have to set expectations before calling the method that throws the exception.

    任何类似于assertThrows(methodCallThatThrows())的内容. Java将尝试在调用assertThrows之前从methodCallThatThrows中获取返回值,因此该处的任何try都无济于事.

    Anything that looks like assertThrows(methodCallThatThrows()). Java will try to get the return value out of methodCallThatThrows before assertThrows is ever invoked, so any try block there can't help.

    这篇关于Junit在等待并处理异常后声明某些内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆