使用SpringFramework的Junit测试不良的thread.sleep()调用。怎么修?
-
09-10-2019 - |
题
我最近加入了一个有一些严重的JUNIT测试问题的小组。一个问题是8分钟长的测试!该测试有几个部分;每个人都会拨打org.springframework.context.applicationeventpublisher.publishevent(),然后是各种时间的thread.sleep(),然后测试条件。
这种方法有几个明显的问题,线程的时机。sleep()调用很脆弱:
测试偶尔在繁忙的机器上失败;和
当测试不会失败时,测试花费太长了。
是否可以处理这些事件的池进行测试,并且是否有呼叫来查看事件级联是否已经静止?
解决方案
您可以覆盖默认值 applicationEventMulticaster
通过将此Bean ID添加到您的应用程序上下文中。
而不是默认 SimpleApplicationEventMulticaster
, ,您可以在此Bean上设置一个taskexecutor,以在多个线程中进行异步发布事件。
或者,您可以实施自己的多层官,该官员打印出哪个事件听众花了很长时间或阻止了哪些事件。这可以帮助您跟踪8分钟测试的真正问题。
有趣的是,SimpleApplicationEventMulticaster的Javadoc,默认情况下在您使用ApplicationContext时默认使用,以下内容:
默认情况下,所有听众都在调用线程中调用。 这允许流氓听众阻止整个应用程序的危险, ,但增加了最小的开销。指定替代的taskexecutor,以使听众在不同的线程中执行,例如从线程池中执行。
其他提示
值得一提的是,实际上称外部服务的测试代码是集成测试而不是单位测试。如果您在这里进行真正的单位测试,则应用模拟替换这些电话。这样,您可以更好地控制返回到业务逻辑的值并测试特定条件。另外,如您所见,由于外部(非代码)情况,这几乎消除了误报。显然,这些测试没有失败,他们期望使用的设施是。
我(故意)避免春季,所以我不确定我是否可以帮助您提供具体细节,而只是看睡眠问题,您可以使用类似的东西 WaitFor
在tempus-fugit(无耻的插头)中进行轮询 Condition
而不是“睡觉和希望”。这不是理想的选择,通常会改变您的测试方式(如前所述)是可取的,但这确实意味着您获得了更细的“等待”,这更有可能避免种族条件 /片状测试,并且通常会加快测试。
查看项目的 文档 有关详细信息,并发回去,如果您觉得有用!