我有一个JUnit类,用于测试系统中的时钟。时钟有一个方法jump(long milliSeconds
,它基本上使时钟跳转到指定的时间,从而将clock currentTime
的实例字段设置为传递给跳转方法的参数。
所以我有三个JUnit方法。在第一个我只是测试时钟的当前时间是0,因为我没有在时钟上调用任何东西。然后,我只是测试使时钟跳转到指定时间,一旦正确反映在当前时间。最后,我几次调用跳转方法,每次跳转后我都会测试当前时间是否正确。
我遇到的问题是,有时我的JUnit测试有时会失败。假设我运行上面三个JUnit方法,然后通过。没关系。然后,如果我再次运行三个,那么第一个失败,因为时钟的当前时间不再是0,而是当前时间是在上一次测试中调用的最后一次跳转。
我对此感到困惑,因为我认为在按顺序执行所有三种JUnit方法之后,它并没有记住"如果我再次运行测试它会怎么做
那么这需要我在@Before setUp()
中将当前时间初始化为0吗?事情是,有时只会出现上述情况。如果我等待5分钟再次运行它。它运行正常。然后如果我再次立即运行它,我会得到同样的错误。
它是否与我将Clock类声明为final的事实有关?或者我已经在其上强制使用Singleton设计模式了?
答案 0 :(得分:1)
您将时钟设计为单例:每个类加载器只有一个Clock实例:Clock.INSTANCE
。很明显,如果测试方法影响时钟状态,下一个方法将找到具有这种新状态的时钟。
你刚刚重新发现了为什么单身人士是一个反模式的原因之一:它很难进行单元测试。每次测试都不应该假设时钟,并在测试前将其置于一个众所周知的初始状态。
或者您可以简单地将Clock设计为可以在测试设置中实例化的普通旧Java对象,并使用IOC容器在运行时在Bean中注入一个唯一的Clock实例。
另外,请注意,单元测试应该是相互独立的。您可能希望执行所有测试,或者只执行其中一个测试,并且它们应该能够以任何顺序运行。
答案 1 :(得分:0)
在JUnit中,不保证测试方法调用的顺序,这在Junit FAQ部分中有解释。
您的实现使用单例,因此在JUnit运行测试的顺序之前公开将影响测试结果。
测试取决于其他测试并不是一个好习惯,但如果您需要确保可以使用TestNG。
要解决这个问题,请使用简单的POJO类,并让一些DI框架处理它。如果它是一个约束,你应该保留你的类,用TestNG测试它或重写你的测试以确保你需要的顺序。即:我认为一个好的测试可以检查较低的指定时间是否会引发异常。