比较两个掷骰子的正确方法是什么?

时间:2015-05-15 13:33:51

标签: java junit throwable

我正在使用JUnit规则立即重新运行任何失败的测试。我的额外要求是,如果重新运行也失败,则由于同样的原因确定它们是否失败。

要做到这一点,我已经调整了this answer的代码来记录失败并进行比较。但是,比较(.equals)始终评估为false,尽管它们由于同样的原因而失败。最好的方法是什么?

  private Statement statement(final Statement base, final Description description) {
    return new Statement() {
      @Override
      public void evaluate() throws Throwable {

        for (int i = 0; i < retryCount; i++) {
          try {
            base.evaluate();
            return;
          } catch (Throwable t) {
            System.err.println(description.getDisplayName() + ": run " + (i + 1) + " failed");

            // Compare this error with the one before it.
            if (errors.size() > 0) {
              if (t.equals(errors.get(errors.size() - 1))) {
                System.out.println("The error is the same as the previous one!");
              } else {
                System.out.println("The error is different from the previous one.");
              }
            }

            errors.add(t);
          }
        }
        System.err.println(description.getDisplayName() + ": giving up after " + retryCount
            + " failures");

        // Throw most recent error.
        throw errors.get(errors.size() - 1);
      }
    };
  }

4 个答案:

答案 0 :(得分:3)

如果只想知道是否是任何类的类型,请使用instance of,如:

if( t instanceof Throwable){
   //... 
}

答案 1 :(得分:1)

异常未正确实施等于。您必须自己比较消息和/或堆栈跟踪。

答案 2 :(得分:1)

你只能比较:

按名称

t.getClass().getName()

或通过instanceof

t instanceof XXXXXXX

答案 3 :(得分:1)

Throwable的平等定义为“相同的Throwable”。 (它比较参考文献。)

“相同的原因”是您需要考虑并为您的应用程序定义的内容。

我们可以定义它的一种方式是“相同的类型和松散相同的throw语句”:

static boolean sameTypeAndLine(Throwable t1, Throwable t2) {
    if (t1.getClass() == t2.getClass()) {
        StackTraceElement[] trace1 = t1.getStackTrace();
        StackTraceElement[] trace2 = t2.getStackTrace();
        return trace1[0].equals(trace2[0]);
    } else {
        return false;
    }
}

但这仍然含糊不清:

  • if (bad1 || bad2) {
        // same throw site, different conditions
        throw new Exception(...);
    }
    
  • // throws NullPointerExeption
    // (was it foo or the result of bar() that was null?)
    Object baz = foo.bar().baz();
    

因此,您可以做的最好的事情是为您的例外明确定义原因

class MyException {
    final Reason reason;

    MyException(Reason reason) {
        this.reason = reason;
    }

    // or a class, or whatever you need
    enum Reason {A, B, C}
}

并检查那些。此外,使用可防止歧义的编码风格。