0

我最近加入了一个有一些严重 JUnit 测试问题的小组。一个问题是 8 分钟的测试!测试有几个部分;每个人都会调用 org.springframework.context.ApplicationEventPublisher.publishEvent(),然后是不同时间的 Thread.sleep(),然后测试条件。

这种方法有几个明显的问题,Thread.sleep() 调用的时间很脆弱:

  • 在繁忙的机器上测试偶尔会失败;和

  • 当测试没有失败时,测试花费的时间太长了。

处理这些事件的池是否可用于测试,是否有调用以查看事件级联是否已停止?

4

3 回答 3

2

值得一提的是,实际调用外部服务的测试代码是集成测试,而不是单元测试。如果你真的在这里进行单元测试,你应该用模拟替换那些调用。这样,您可以更好地控制返回到业务逻辑的值并测试特定条件。此外,正如您所见,这几乎消除了由于外部(非代码)情况导致的误报。显然,这些测试并没有失败,他们期望使用的设施是。

于 2010-12-13T21:02:34.420 回答
1

applicationEventMulticaster您可以通过将此 bean id 添加到应用程序上下文来覆盖默认值。

SimpleApplicationEventMulticaster您可以在此 bean 上设置一个 TaskExecutor而不是 default ,以在多个线程中异步执行事件发布。

或者您可以实现自己的多播器,它会打印出哪个事件侦听器花费了这么长时间或阻塞了多长时间以及发生了哪些事件。这可以帮助您找出 8 分钟测试用例的真正问题。

有趣的是,Spring 在使用 ApplicationContext 时默认使用的 SimpleApplicationEventMulticaster 的 JavaDoc 声明如下:

默认情况下,所有侦听器都在调用线程中调用。这允许流氓侦听器阻塞整个应用程序的危险,但增加的开销最小。指定一个替代的 TaskExecutor 让监听器在不同的线程中执行,例如从一个线程池中。

于 2010-12-13T22:52:32.270 回答
0

I (intentionally) avoid Spring so I'm not sure I can help with the specifics but just looking at the sleep issue, you can use something like WaitFor in tempus-fugit (shameless plug) to poll for a Condition rather than "sleep and hope". It's not ideal and usually a change in the way you test (as suggested before) is preferable but it does mean you get finer grained "waits" which are more likely to avoid race-conditions / flaky tests and generally speed up the test.

See the project's documentation for details and post back if you find it useful!

于 2010-12-15T08:46:49.620 回答