【问题标题】:JUnit: Enable assertions in class under testJUnit:在被测类中启用断言
【发布时间】:2010-12-20 08:38:09
【问题描述】:

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

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

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

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

【问题讨论】:

  • 只是一个一般性问题。如果你真的想对你的代码进行彻底的单元测试,你不应该在启用和不启用断言的情况下进行测试吗?断言非常有用的一件事是引入了意想不到的副作用。
  • 顺便说一句。你是如何运行 JUnit 测试用例的?如果你有一些构建管理器(ant、maven),默认添加这个开关应该很简单
  • @Alexander:这不是一个坏主意。 @jitter:你当然是对的。 Maven 似乎默认启用断言。我之前没有注意到 Eclipse 对此有偏好设置。问题是这些设置可以在你背后改变......
  • 您考虑过我重新编写的答案吗?我为您的问题提出了三种可能的解决方案,它们都有效(经过测试)

标签: java junit assertions


【解决方案1】:

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

复选框旁边的全文是

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

【讨论】:

  • 您的 Eclipse 中是否有任何类型的单元测试插件?我找不到那个选项。
  • 不,它是标准 Eclipse 安装的一部分
  • 您使用哪个版本的 Eclipse?
  • 对不起,这是很久以前的事了。我的 PC 上不再安装 Eclipse :(
  • 我正在使用 Juno。它在 Window -> Preferences -> Java -> JUnit
【解决方案2】:

或者,您可以编译代码,使断言不能被关闭。在 Java 6 下,您可以使用 "fa.jar – Force assertion check even when not enabled",这是我的一个小技巧。

【讨论】:

  • 好主意!但是,如果它在 Eclipse 中不起作用,它对我不起作用。
【解决方案3】:

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

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

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

【讨论】:

  • 除非断言被证明会使代码减慢到出现问题的程度,否则我宁愿一直使用它们。前置条件/​​后置条件和任何其他类型的断言语句 - 如果您花时间编写它,为什么要关闭它?
  • 如果它是一个先决条件,那么我的论点是它不值得断言,应该检查并作为 IllegalArgumentException 或任何适用于该先决条件的异常抛出。不过,后置条件完全值得断言,假设它检查的内容不仅仅是@NotNull。
  • 断言对于私有方法仍然有用,您希望在开发期间而不是在生产中检查先决条件。除非有充分的理由不这样做,否则更喜欢公共接口上的异常。
【解决方案4】:

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

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");
    }
}

【讨论】:

  • 这在我的情况下不起作用。它依赖于加载类的顺序。
  • 对不起,但这不会按预期工作。加载和初始化类时必须启用断言,并且在类加载器上设置默认断言状态只会影响稍后加载的类。
猜你喜欢
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
相关资源
最近更新 更多