我在这里假设,如果断言失败,您希望测试通过,但是如果断言成功,那么测试也应该通过。
最简单的方法是使用TestRule。TestRule提供了在运行测试方法之前和之后执行代码的机会。这是一个例子:
public class ExpectedFailureTest { public class ExpectedFailure implements TestRule { public Statement apply(Statement base, 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) { if (description.getAnnotation(Deprecated.class) != null) { // you can do whatever you like here. System.err.println("test failed, but that's ok:"); } else { throw e; } } } }; } } @Rule public ExpectedFailure expectedFailure = new ExpectedFailure(); // actually fails, but we catch the exception and make the test pass. @Deprecated @Test public void testExpectedFailure() { Object o = null; o.equals("foo"); } // fails @Test public void testExpectedFailure2() { Object o = null; o.equals("foo"); }}首先,请注意第一种方法标记为
@Deprecated。我将其用作要忽略任何断言失败的方法的标记。您可以做任何您想识别的方法,这只是一个例子。
接下来,在中
ExpectedFailure#apply(),当我执行base.evaluate()时,我捕获了任何Throwable(包括AssertionError),并且如果该方法用@Deprecated标注,则忽略该错误。您可以执行任何逻辑,根据版本号,某些文本等来决定是否忽略该错误。您还可以将动态确定的标志传递给ExpectedFailure,以使其在某些版本号下失败:
public void unmarshalleddocumentHasExpectedValue() { doc = unmarshaller.unmarshal(getResourceAsStream("mydoc.xml")); expectedFailure.setExpectedFailure(doc.getVersionNumber() < 3000); final ST title = doc.getTitle(); assertThat(doc.getTitle().toStringContent(), equalTo("Expected"));}有关更多示例,请参见ExternalResource和ExpectedException
忽略预期的失败测试而不是通过测试
如果要将测试标记为“已忽略”而不是“成功”,则它会变得有些复杂,因为在执行测试之前会忽略它们,因此您必须将测试追溯标记为已忽略,这将涉及构造自己的Runner。首先,请参见我对如何在套件中定义JUnit方法规则的回答。。或问另一个问题。



