当前位置: 首页 > 知识库问答 >
问题:

Junit 在等待和处理异常后断言某些内容

孟楷
2023-03-14

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

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作为更好的解决方案也是可以接受的。

更好的意思是,如果我能在测试中避免try/catch甚至多次try/catch。在其他语言或jAsutter中,我认为即使在Spring也有这样的语句:

assertThrows(method(..)) //PseudoCode

我认为Mockito或JUnit4.x也有类似的情况。

我知道关于

@Test(expected=Exception)

但这只有在我期望一次投掷并且测试结束后才可以接受。

共有3个答案

东门茂实
2023-03-14

使用Java8,您可以使用鱼缸库。

@Test
public void testFooThrowsAtFirstAndSecondTime(){
  Throwable firstException = exceptionThrownBy(() -> foo());
  assertEquals(Exception.class, firstException.getClass());

  Throwable secondException = exceptionThrownBy(() -> foo());
  assertEquals(Exception.class, secondException.getClass());

  foo()
}

Java 6和7也可以使用这个库。但是你必须使用匿名类。

@Test
public void testFooThrowsAtFirstAndSecondTime(){
  Throwable firstException = exceptionThrownBy(new Statement() {
    public void evaluate() throws Throwable {
      foo();
    }
  });
  assertEquals(Exception.class, firstException.getClass());

  Throwable secondException = exceptionThrownBy(new Statement() {
    public void evaluate() throws Throwable {
      foo();
    }
  });
  assertEquals(Exception.class, secondException.getClass());

  foo()
}
薛弘济
2023-03-14

这里的关键是,如果您想在异常后恢复执行,try块是至关重要的。您可以将其分解到一个方法或库中,但是必须在您的测试方法中调用它。

有用的东西:

>

  • 你和nrainier引用的久经考验的fail()成语,我更喜欢:

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

    catch异常是一个库,与Mockito一样,它包装传递的对象,并在每个方法周围放置一个try块。Mockito关于final方法和类的警告在这里也适用,所以这并不总是有效的。

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

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

    任何像< code>assertThrows(() -这样的解决方案

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

    ...在Java 6/7中。重要的是,assertThrows在method that rows之前被调用,因此它可以调用method that rows。感谢Stefan指出了Fishbowl,但是您自己也可以很容易地写出一个等价的例子:

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

    不起作用的事物:

    >

  • @Test(expected=YourException.class)将向上堆栈,进入JUnit包装测试方法tryblock。此后,控件再也不会返回到测试方法。

    JUnit4的< code > expected exception @规则看起来很诱人,但是因为它包装了整个测试方法,所以您必须在调用抛出异常的方法之前设置期望值。

    任何类似于< code > assert throws(methodcallthithrows())的内容。在调用< code>assertThrows之前,Java将尝试从< code > methodcallthithrows 中获取返回值,因此任何< code>try块都无济于事。

  • 东方英豪
    2023-03-14

    我认为每个方法调用一行代码是不可能的。

    我会这样写测试:

    @Test
    public void testFooThrowsAtFirstAndSecondTime() throws Exception {
      try {
        foo();
        fail("foo did not throw an exception");
      } catch (Exception ex) { }
    
      try{
        foo(); 
        fail("foo did not throw an exception");
      } catch (Exception ex) { }
    
      foo();
    }
    
     类似资料:
    • 80386实地址模式下的中断和异常处理与8086是一样的。中断和异常通过中断表指向处理函数。处理器将中断和异常标识符乘以4来获得其在中断表的索引。中断表是指向处理函数的长指针。当中断发生时,处理器将CS:IP压栈,关中断,清TF(单步标志位),然后将控制权交给中断表指向的函数。在处理函数末尾的IRET执行相反的过程,并将控制权交还给被中断的进程。 80386的中断处理与8086的最大不同之处在于中

    • 我想使用异步并等待处理承诺。我想在下面的示例中使用这个方法: 在执行时,它给了我一个错误 错误: UnhandledPromiseRejectionWarning:未处理得承诺拒绝.这个错误可能是由于抛出一个没有catch块的异步函数内部,或者是由于拒绝了一个未用.catch()处理的承诺。(拒绝ID:3)

    • 我有以下兔子听者: 我需要将listener配置为在它处理一条消息后等待15分钟,然后再接收下一条消息。不需要在此方法中等待。我所需要的只是在处理完一条后不接收任何消息。可以通过来完成,但我不确定这是否是实现这一点的最佳方法。对于这种情况有没有rabbitmq的配置?

    • 在JUnit5中有更好的方法来断言方法抛出异常吗? 目前,我必须使用@规则来验证我的测试是否抛出了异常,但这对于我期望多个方法在我的测试中抛出异常的情况不起作用。

    • 问题内容: 如何惯用JUnit4来测试某些代码引发异常? 虽然我当然可以做这样的事情: 我记得在这种情况下,有一个批注或一个Assert.xyz或一些不太灵活的JUnit东西。 问题答案: JUnit 4 有对此的支持:

    • 一个人如何断言在一个游戏的主体内的内容!JSON操作结果值?我正在从一个操作返回一个新的(甚至是空的)JSON ObjectNode,并试图在单元测试的结果中对其进行断言,但在response.wrappresult.body中没有看到值(null或其他)。 例如,在我的操作中,如果返回一个null JSON对象节点, 或者如果返回测试值, 然后我根据结果写一个测试, 谢了!