JUnit:在被测试的类中启用断言
我已经在JUnit测试套件中没有失败的Java assert
语句多次,因为在JUnit的JVM实例中没有启用断言。 要清楚,这些是实现中的“黑盒子”断言(检查不变量等),而不是JUnit测试本身定义的断言。 当然,我想在测试套件中捕获任何这样的断言失败。
显而易见的解决方案是每次运行JUnit时都要非常小心地使用-enableassertions
,但我更喜欢更强大的解决方案。 一种替代方法是将以下测试添加到每个测试类:
@Test(expected=AssertionError.class) public void testAssertionsEnabled() { assert(false); }
有没有更自动的方法来实现这一目标? JUnit的系统范围配置选项? 我可以在setUp()
方法中进行动态调用吗?
在Eclipse中,您可以转到Windows
→ Preferences
→ Java
→ JUnit
,它可以选择在每次创建新的启动配置时添加-ea
。 它-ea
选项添加到调试配置中。
复选框旁边的全文是
在创建新的JUnit启动配置时,将“-ea”添加到VM参数
我建议三种可能(简单?)修复,在快速测试后对我有用(但你可能需要检查使用静态初始化程序块的副作用)
1.)将静态初始化程序块添加到依赖于启用断言的那些测试用例中
import .... public class TestXX.... ... static { ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } ... @Test(expected=AssertionError.class) ... ...
2.)创建一个基类,所有测试类都扩展,需要启用断言
public class AssertionBaseTest { static { //static block gets inherited too ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } }
3.)创建一个运行所有测试的测试套件
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ //list of comma-separated classes /*Foo.class, Bar.class*/ }) public class AssertionTestSuite { static { //should run before the test classes are loaded ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } public static void main(String args[]) { org.junit.runner.JUnitCore.main("AssertionTestSuite"); } }
或者,您可以编译代码,以便无法关闭断言。 在Java 6下,您可以使用“fa.jar – 强制断言检查,即使未启用” ,这是我的一个小黑客。
正如我的一位朋友所说…如果你要关掉它,为什么要花时间写一个断言呢?
鉴于逻辑,所有断言语句应变为:
if(!(....)) { // or some other appropriate RuntimeException subclass throw new IllegalArgumentException("........."); }
以你可能想要的方式回答你的问题:-)
import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ FooTest.class, BarTest.class }) public class TestSuite { @BeforeClass public static void oneTimeSetUp() { ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } }
然后运行测试套件而不是每个测试。 这应该(在我的测试中工作,但我没有读取JUnit框架代码的内部结果)导致在加载任何测试类之前设置断言状态。