Mark unit test as an expected failure in JUnit

后端 未结 6 1927
滥情空心
滥情空心 2020-12-09 01:05

How can I mark a test as an expected failure in JUnit 4?

In this case I want to continue to run this test until something is patched upstream. Ignoring the test goes

6条回答
  •  时光取名叫无心
    2020-12-09 01:34

    I've taken Matthew's answer a step further and actually implemented an @Optional annotation you could use instead of the @Deprecated marker annotation he mentions in his answer. Although simple, I'll share the code with you, maybe it's of help for someone:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Optional {
    
      /**
       * Specify a Throwable, to cause a test method to succeed even if an exception
       * of the specified class is thrown by the method.
       */
      Class[] exception();
    }
    

    With a simple alteration of Matt's ExpectedFailure class:

    public class ExpectedFailure implements TestRule {
    
      @Override
      public Statement apply(final Statement base, final Description description) {
        return statement(base, description);
      }
    
      private Statement statement(final Statement base, final Description description) {
        return new Statement() {
    
          @Override
          public void evaluate() throws Throwable {
            try {
              base.evaluate();
            } catch (Throwable e) {
              // check for certain exception types
              Optional annon = description.getAnnotation(Optional.class);
              if (annon != null && ArrayUtils.contains(annon.exception(), e.getClass())) {
                // ok
              } else {
                throw e;
              }
            }
          }
        };
      }
    }
    

    You can now annotate your test method with @Optional and it will not fail, even if the given type of exception is raised (provide one or more types you would like the test method to pass):

    public class ExpectedFailureTest {
    
      @Rule public ExpectedFailure expectedFailure = new ExpectedFailure();
    
      // actually fails, but we catch the exception and make the test pass.
      @Optional(exception = NullPointerException.class)
      @Test public void testExpectedFailure() {
          Object o = null;
          o.equals("foo");
      }
    
    }
    

    [UPDATE]

    You could also rewrite your tests using JUnit's org.junit.Assume instead of the tradtional org.junit.Assert, if you want your tests to pass even if the assumption does not hold.

    From Assume's JavaDoc:

    A set of methods useful for stating assumptions about the conditions in which a test is meaningful.A failed assumption does not mean the code is broken, but that the test provides no useful information. The default JUnit runner treats tests with failing assumptions as ignored.

    Assume is available since JUnit 4.4

提交回复
热议问题