【发布时间】:2016-03-29 11:44:04
【问题描述】:
假设我有以下应该测试的方法:
@Autowired
private RoutingService routingservice;
public void methodToBeTested() {
Object objectToRoute = initializeObjectToRoute();
if (someConditions) {
routingService.routeInOneWay(objectToRoute);
} else {
routingService.routeInAnotherWay(objectToRoute);
}
}
在这种情况下,RoutingService 在单独的线程中运行,因此在它的构造函数中我们有以下内容:
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.start();
问题是RoutingService 改变了objectToRoute 的状态,这正是我想要检查的,但这不会立即发生,因此测试失败。但是,如果我添加 Thread.sleep() 则它可以工作,但据我所知,这是不好的做法。
在这种情况下如何避免Thread.sleep()?
【问题讨论】:
-
在单元测试中使用
Thread.sleep并不是一个坏习惯,因为您所做的只是模仿时间的流逝,这对于某些单元测试来说是必要的。人们说使用Thread.sleep是一种不好的做法的原因是因为它有时被用作修复竞争条件的尝试。您是只在测试中使用Thread.sleep,还是在您的源代码中使用? -
当您测试线程代码时,您将如何确保您的单元测试不是片状的?他们总是以确定性的方式执行。我认为模拟服务类是一个更好的选择
-
我只在测试中使用睡眠,但发现很多地方人们提到睡眠在单元测试中通常不是那么好。例如,SonarLint 插件也抱怨说它是违规的,并给出以下描述:“在测试中使用 Thread.sleep 通常是一个坏主意。它会创建脆弱的测试,可能会因环境而无法预测地失败(“传递我的机器!”)或加载。”
-
同意本。我们在 Maven 构建期间运行 JUnit 测试,当前线程不会等待多线程进程,例如 JMS 交互和外部性能监控。 Thread.sleep 是我们用来确保这些进程在线程被杀死之前完成的。
-
你不同意 Sleep 至少会使单元测试变慢吗?我不应该尽量避免吗?
标签: java multithreading unit-testing junit