Java JUnit测试用例中的Thread.sleep
我正在写一个测试用例来测试一个对象的行为 当对象被实例化时,它必须仅在500毫秒内被调用时才允许调用方法,比如call(),否则它必须抛出异常 我将Junit测试用例设计为:Java JUnit测试用例中的Thread.sleep,java,junit,Java,Junit,我正在写一个测试用例来测试一个对象的行为 当对象被实例化时,它必须仅在500毫秒内被调用时才允许调用方法,比如call(),否则它必须抛出异常 我将Junit测试用例设计为: @Test(expected = IllegalStateException.class) public void testCallAfterTimeout() { MyObject o= new MyObject(); //To ensure the timeout is occurred Thr
@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
MyObject o= new MyObject();
//To ensure the timeout is occurred
Thread.sleep(1000);
o.call();
}
class MyObject
{
public MyObject()
{
this(new Clock());
}
// Protected so only the test case can access it
protected MyObject(Clock clock)
{
// Save clock as local variable, store creation time etc.
}
}
你认为这是一个好的做法还是我应该遵循另一种方法
非常感谢不管这有什么意义,也不管你是在自找麻烦 如果您决定60分钟后需要超时,您会等待测试一小时吗? 超时应该是MyObject的参数,因此您可以将其设置为某个小值以进行测试(甚至可以设置为0以在测试时强制alwyas超时) 其次,如果您真的想拥有可测试的时间相关函数,那么时间和超时应该与主逻辑(MyObject类)分开处理。例如,可以使用Method canCallMethod()创建Timekeeper类,该类由MyObject类调用(并在构造时设置)。通过这种方式,在测试中,您可以使用自己的计时器实现初始化MyObject类,该计时器实现返回true或false,并验证MyObject类的行为是否符合预期。
MyObject可以具有始终使用“实时”计时器的默认构造函数,这样外部世界就不会被迫处理计时器内部。在测试用例中使用(实时)时间有两个问题:
Thread.sleep()
时,这甚至更加困难@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
MyObject o= new MyObject();
// Example function that you could make
advanceClock(1000, TimeUnit.MILLISECONDS)
o.call();
}
在你的对象中,你必须注入一个时钟<代码>MyObject可能如下所示:
@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
MyObject o= new MyObject();
//To ensure the timeout is occurred
Thread.sleep(1000);
o.call();
}
class MyObject
{
public MyObject()
{
this(new Clock());
}
// Protected so only the test case can access it
protected MyObject(Clock clock)
{
// Save clock as local variable, store creation time etc.
}
}
在Java8中提供了一种机制,请参见示例。但您也可以轻松实现自己的安静 为什么首先要这样做?如果您真的想测试这个特定的需求,您将很难找到更好的方法。可能您可以配置超时,并使用最短的测试时间。正如上面所暗示的,一个问题是为什么您的其他对象会这样做?但撇开这一点不谈,这种方法似乎很好,尽管它的粒度相当粗;1000毫秒比500毫秒长得多,如果我删除系统时钟的隐式依赖关系,用一个“可存根的”时钟替换,时间会立即流逝呢?考虑到当前的模拟框架,这似乎过于工程化了。简单地提供一个受保护的方法就足以模拟它进行测试。这是个人喜好,但我不喜欢部分模拟,因为被测试对象的模拟方法感觉是错误的,并建议将这种逻辑委托给其他地方==过度工程化。我认为测试应该从务实的角度进行:让测试关注部分的复杂性预算,但一定要将其保持在最低限度。因此,如果有机会在测试对象内部模拟出一种策略方法,那么一定要抓住它。请记住,复杂性本身会导致维护和正确性问题,而测试正是为了保护您免受这些问题的影响。