0

我有一个 JUnit 类,用于测试我系统中的时钟。时钟有一个方法jump(long milliSeconds,它基本上使时钟跳转到指定的时间,因此将时钟的实例字段设置为currentTime传递给跳转方法的参数。

所以我有三个 JUnit 方法。首先,我只是测试时钟的当前时间是否为 0,因为我没有在时钟上调用任何内容。然后我只是在测试让时钟跳到指定时间一次是否正确反映在当前时间上。最后,我调用了几次跳转方法,每次跳转后我都在测试当前时间是否正确。

我遇到的问题是有时我的 JUnit 测试通过有时会失败。假设我运行上述三个 JUnit 方法一次,它通过了。没关系。然后,如果我再次运行这三个,那么第一个会失败,因为时钟的当前时间不再是 0,而是当前时间是上次测试中调用的最后一次跳转。

我对此感到困惑,因为我认为在依次执行所有三个 JUnit 方法之后,如果我再次运行测试,它就不会“记住”它做了什么。

那么这是否需要我将当前时间初始化为 0 @Before setUp()?问题是只是有时会发生上述情况。如果我等待 5 分钟并再次运行它。它运行良好。然后,如果我立即再次运行它,我会得到同样的错误。

这可能与我将 Clock 类声明为 final 的事实有关吗?或者我已经在它上面执行了单例设计模式?

4

2 回答 2

1

您将 Clock 设计为单例:每个类加载器只有一个 Clock 实例:Clock.INSTANCE。所以很明显,如果一个测试方法影响了时钟的状态,下一个方法会找到这个新状态的时钟。

您刚刚重新发现了单例是反模式的原因之一:难以进行单元测试。每个测试都不应该对时钟做任何假设,并在测试之前将其置于众所周知的初始状态。

或者您可以简单地将 Clock 设计为一个普通的旧 Java 对象,您可以在测试设置中对其进行实例化,并使用 IOC 容器在运行时在您的 bean 中注入一个唯一的 Clock 实例。

另外,请注意,单元测试应该彼此独立。您可能想要执行所有测试,或者只执行其中一个,并且它们应该能够以任何顺序运行。

于 2012-11-18T17:15:02.643 回答
0

在 JUnit 中,不保证测试方法调用的顺序,这在 Junit FAQ部分中进行了解释。

您的实现使用的是单例,因此在 JUnit 运行测试的顺序之前暴露会影响测试结果。

测试相互依赖不是一个好习惯,但是如果您需要确保可以使用 TestNG。

To fix that use a simple POJO class and let some DI framework handle that. If it's a constraint and you should preserve your class as it, test it with TestNG or rewrite your tests to ensure the order that you need. I.e: I think that a good test could be check that a lower specified time could throws an Exception.

于 2012-11-18T17:41:37.793 回答