30

由于在 JUnit 的 JVM 实例中没有启用断言,我曾多次被assertJUnit 测试套件中没有失败的 Java 语句所困扰。需要明确的是,这些是实现内部的“黑盒”断言(检查不变量等),而不是 JUnit 测试本身定义的断言。当然,我想在测试套件中捕获任何此类断言失败。

显而易见的解决方案是在我运行 JUnit 时要非常小心地使用-enableassertions,但我更喜欢更健壮的解决方案。一种替代方法是将以下测试添加到每个测试类:

  @Test(expected=AssertionError.class)
  public void testAssertionsEnabled() {
    assert(false);
  }

有没有更自动的方法来实现这一点?JUnit 的系统范围配置选项?我可以在setUp()方法中进行动态调用吗?

4

4 回答 4

21

在 Eclipse 中,您可以转到WindowsPreferencesJavaJUnit,其中有一个选项可以在-ea每次创建新的启动配置时添加。它也将-ea选项添加到调试配置。

复选框旁边的全文是

创建新的 JUnit 启动配置时将“-ea”添加到 VM 参数

于 2010-08-02T20:00:10.337 回答
5

我提出了三个可能的(简单的?)修复,在快速测试后对我有用(但您可能需要检查使用静态初始化块的副作用)

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");
    }
}
于 2009-11-25T16:18:21.540 回答
4

或者,您可以编译您的代码,使断言不能被关闭。在 Java 6 下,您可以使用“fa.jar – 即使未启用也强制进行断言检查”,这是我的一个小技巧。

于 2009-11-26T02:20:13.520 回答
1

正如我的一个朋友所说......如果你只是要关闭它,为什么要花时间写一个断言?

鉴于该逻辑,所有断言语句都应变为:

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 框架代码的内部内容)会导致在加载任何测试类之前设置断言状态。

于 2009-11-25T17:37:16.390 回答