Java 我打开断言的JUnit规则不';在我们詹金斯的身材上似乎做不到

Java 我打开断言的JUnit规则不';在我们詹金斯的身材上似乎做不到,java,junit,assertions,Java,Junit,Assertions,我希望整个代码中的断言失败会导致测试失败 我有这样一个JUnit规则: public class AcmeTestRule implements TestRule { @Override public Statement apply(final Statement statement, Description description) { return new Statement() { @Override publ

我希望整个代码中的断言失败会导致测试失败

我有这样一个JUnit规则:

public class AcmeTestRule implements TestRule {
    @Override
    public Statement apply(final Statement statement, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                ClassLoader classLoader = getClass().getClassLoader();
                classLoader.clearAssertionStatus();
                classLoader.setDefaultAssertionStatus(true);
                //classLoader.setPackageAssertionStatus("com.acme", true); // no effect

                statement.evaluate();
            }
        }
    }
}
public abstract class AcmeTestCase {
    @ClassRule
    public static final AcmeTestRule acmeTestRule = new AcmeTestRule();
}
它是基于这样一个基本测试类:

public class AcmeTestRule implements TestRule {
    @Override
    public Statement apply(final Statement statement, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                ClassLoader classLoader = getClass().getClassLoader();
                classLoader.clearAssertionStatus();
                classLoader.setDefaultAssertionStatus(true);
                //classLoader.setPackageAssertionStatus("com.acme", true); // no effect

                statement.evaluate();
            }
        }
    }
}
public abstract class AcmeTestCase {
    @ClassRule
    public static final AcmeTestRule acmeTestRule = new AcmeTestRule();
}
然后,为了确认规则本身是否有效,我进行了以下测试:

public class TestAcmeTestRule extends AcmeTestCase4 {
    @Test
    public void testAssertions() {
        try {
            assert false;
        } catch (AssertionError) {
            // good.
            return;
        }

        fail("Didn't throw AssertionError on assert false");
    }
}
在我们的自动构建上测试失败,因为“assert false”仍然没有引发异常。完全相同的测试通过从IDE运行。我们没有设置任何命令行标志来启用断言(尽管IDE可能在我们背后这么做)

顺便说一句,如果我这样做:

public class TestAcmeTestRule {
    @ClassRule
    public static final AcmeTestRule acmeTestRule = new AcmeTestRule();

    @Test
    public void testAssertions() {
        try {
            assert false;
        } catch (AssertionError) {
            // good.
            return;
        }

        fail("Didn't throw AssertionError on assert false");
    }
}
结果测试现在在IDE中也失败了。我所做的只是将规则从抽象类移到测试类中


我认为这是一个奇怪的类加载问题。我的理论是:断言状态仅在读取字节码时使用,因此当您运行字节码时,更改值为时已晚。

ClassLoader.setDefaultAssertionStatus(以及所有类似方法)的问题是,它们对已加载的类没有影响。从

此设置确定此类加载器加载并在中初始化的类在默认情况下是否启用或禁用断言

因此,您无法在代码中可靠地启用断言,只要您不确保在加载所有其他类之前执行断言(这可能容易出错)


这在IDE中起作用的原因可能是IDE倾向于通过传递适当的命令行参数来启用断言,或者类加载的顺序可能不同。

第二个示例似乎证实了这不是通过命令行完成的。我假设JUnitTask和IDEA的JUnitRunner之间的类加载顺序不同。