8个分支机构可以尝试使用资源 - 可以覆盖jacoco吗? [英] 8 branches for try with resources - jacoco coverage possible?

查看:127
本文介绍了8个分支机构可以尝试使用资源 - 可以覆盖jacoco吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用try资源的代码,而在jacoco中它只有一半被覆盖。所有的源代码行都是绿色的,但我得到一个黄色的小符号,告诉我8个分支中只有4个被覆盖。

I've got some code that uses try with resources and in jacoco it's coming up as only half covered. All the source code lines are green, but I get a little yellow symbol telling me that only 4 of 8 branches are covered.

我无法弄清楚所有分支是什么,以及如何编写涵盖它们的代码。三个可能的地方抛出 PipelineException 。这些是 createStageList() processItem()和隐含的 close()

I'm having trouble figuring out what all the branches are, and how to write code that covers them. Three possible places throw PipelineException. These are createStageList(), processItem() and the implied close()


  1. 不抛出任何异常,

  2. 从<$ c $抛出异常c> createStageList()

  3. 中抛出异常processItem()

  4. 抛出异常close()

  5. processItem()中抛出异常关闭()

  1. Not throwing any exceptions,
  2. throwing an exception from createStageList()
  3. throwing an exception from processItem()
  4. throwing an exception from close()
  5. throwing an exception from processItem() and close()

我想不到在任何其他情况下,我仍然只有8个中的4个被覆盖。

I can't think of any other cases, yet I still only have 4 of 8 covered.

有人可以向我解释为什么它是4的4并且无论如何都要击中所有8个分支?我不熟悉decyrpting /阅读/解释字节码,但也许你是...... :)我已经看过 https://github.com/jacoco/jacoco/issues/82 ,但它和它引用的问题都没有多大帮助(除了注意这是由于编译器生成的块)

Can someone explain to me why it's 4 of 8 and is there anyway to hit all 8 branches? I'm not skilled with decyrpting/reading/interpreting byte code, but maybe you are... :) I've already seen https://github.com/jacoco/jacoco/issues/82, but neither it nor the issue it references help very much (other than noting that this is due to compiler generated blocks)

嗯,就在我写完这篇文章的时候,我想到了上面提到的什么案例可能没有经过测试......如果我拿到它,我会发一个答案对。我确定这个问题及其答案在任何情况下都会对某人有所帮助。

Hmm, just as I finish writing this I had a thought on what case(s) might not be not tested by what I mention above... I'll post an answer if I got it right. I'm sure this question and it's answer will help someone in any case.

编辑:不,我没找到。抛出RuntimeExceptions(不是由catch块处理)没有覆盖任何更多的分支

Nope, I didn't find it. Throwing RuntimeExceptions (not handled by the catch block) didn't cover any more branches

推荐答案

好吧我不能告诉你什么Jacoco的确切问题是,但我可以告诉你如何编译Try With Resources。基本上,有很多编译器生成的开关来处理在不同点抛出的异常。

Well I can't tell you what the exact problem with Jacoco is, but I can show you how Try With Resources is compiled. Basically, there are a lot of compiler generated switches to handle exceptions thrown at various points.

如果我们采用以下代码并编译它

If we take the following code and compile it

public static void main(String[] args){
    String a = "before";

    try (CharArrayWriter br = new CharArrayWriter()) {
        br.writeTo(null);
    } catch (IOException e){
        System.out.println(e.getMessage());
    }

    String a2 = "after";
}

然后反汇编,我们得到

.method static public main : ([Ljava/lang/String;)V
    .limit stack 2
    .limit locals 7
    .catch java/lang/Throwable from L26 to L30 using L33
    .catch java/lang/Throwable from L13 to L18 using L51
    .catch [0] from L13 to L18 using L59
    .catch java/lang/Throwable from L69 to L73 using L76
    .catch [0] from L51 to L61 using L59
    .catch java/io/IOException from L3 to L94 using L97
    ldc 'before'
    astore_1
L3:
    new java/io/CharArrayWriter
    dup
    invokespecial java/io/CharArrayWriter <init> ()V
    astore_2
    aconst_null
    astore_3
L13:
    aload_2
    aconst_null
    invokevirtual java/io/CharArrayWriter writeTo (Ljava/io/Writer;)V
L18:
    aload_2
    ifnull L94
    aload_3
    ifnull L44
L26:
    aload_2
    invokevirtual java/io/CharArrayWriter close ()V
L30:
    goto L94
L33:
.stack full
    locals Object [Ljava/lang/String; Object java/lang/String Object java/io/CharArrayWriter Object java/lang/Throwable
    stack Object java/lang/Throwable
.end stack
    astore 4
    aload_3
    aload 4
    invokevirtual java/lang/Throwable addSuppressed (Ljava/lang/Throwable;)V
    goto L94
L44:
.stack same
    aload_2
    invokevirtual java/io/CharArrayWriter close ()V
    goto L94
L51:
.stack same_locals_1_stack_item
    stack Object java/lang/Throwable
.end stack
    astore 4
    aload 4
    astore_3
    aload 4
    athrow
L59:
.stack same_locals_1_stack_item
    stack Object java/lang/Throwable
.end stack
    astore 5
L61:
    aload_2
    ifnull L91
    aload_3
    ifnull L87
L69:
    aload_2
    invokevirtual java/io/CharArrayWriter close ()V
L73:
    goto L91
L76:
.stack full
    locals Object [Ljava/lang/String; Object java/lang/String Object java/io/CharArrayWriter Object java/lang/Throwable Top Object java/lang/Throwable
    stack Object java/lang/Throwable
.end stack
    astore 6
    aload_3
    aload 6
    invokevirtual java/lang/Throwable addSuppressed (Ljava/lang/Throwable;)V
    goto L91
L87:
.stack same
    aload_2
    invokevirtual java/io/CharArrayWriter close ()V
L91:
.stack same
    aload 5
    athrow
L94:
.stack full
    locals Object [Ljava/lang/String; Object java/lang/String
    stack 
.end stack
    goto L108
L97:
.stack same_locals_1_stack_item
    stack Object java/io/IOException
.end stack
    astore_2
    getstatic java/lang/System out Ljava/io/PrintStream;
    aload_2
    invokevirtual java/io/IOException getMessage ()Ljava/lang/String;
    invokevirtual java/io/PrintStream println (Ljava/lang/String;)V
L108:
.stack same
    ldc 'after'
    astore_2
    return
.end method

对于那些不会说字节码的人来说,这大致相当于以下伪Java。我不得不使用gotos,因为字节码并不真正对应于Java控制流。

For those who don't speak bytecode, this is roughly equivalent to the following pseudo Java. I had to use gotos because the bytecode doesn't really correspond to Java control flow.

正如你所看到的,有很多案例可以处理各种可能性抑制异常。能够涵盖所有这些案件是不合理的。实际上,第一次尝试块上的转到L59 分支是不可能达到的,因为第一次捕获Throwable将捕获所有异常。

As you can see, there are a lot of cases to handle the various possibilities of suppressed exceptions. It's not reasonable to be able to cover all these cases. In fact, the goto L59 branch on the first try block is impossible to reach, since the first catch Throwable will catch all exceptions.

try{
    CharArrayWriter br = new CharArrayWriter();
    Throwable x = null;

    try{
        br.writeTo(null);
    } catch (Throwable t) {goto L51;}
    catch (Throwable t) {goto L59;}

    if (br != null) {
        if (x != null) {
            try{
                br.close();
            } catch (Throwable t) {
                x.addSuppressed(t);
            }
        } else {br.close();}
    }
    break;

    try{
        L51:
        x = t;
        throw t;

        L59:
        Throwable t2 = t;
    } catch (Throwable t) {goto L59;}

    if (br != null) {
        if (x != null) {
            try{
                br.close();
            } catch (Throwable t){
                x.addSuppressed(t);
            }
        } else {br.close();}
    }
    throw t2;
} catch (IOException e) {
    System.out.println(e)
}

这篇关于8个分支机构可以尝试使用资源 - 可以覆盖jacoco吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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