1

我有 Swing java 应用程序,它与几个“播放器”进行网络通信,这些播放器对象表示为播放器对象,每个播放器对象都有自己的通信线程。该应用程序有一个管理所有玩家对象的“团队”对象。几个 UI 组件通过 Team 对象监听玩家传递的事件。

在我的设计中,团队对象使用 invokeLater 触发 Swing 线程上的所有事件,这样我的应用程序的其余部分就不必为线程问题而烦恼。但是,我不知道如何在 JUnit 测试中测试 Team 类。

多一点背景。起初,我让 Team 对象在玩家对象线程上触发其事件(根本没有线程切换)。Team 单元测试成功了,但是我在 UI 中使用 invokeLaters 遇到了许多线程问题,并且在所有地方都进行了同步。然后我决定通过让 Team 对象在 Swing 线程上触发事件来简化线程模型,但是现在 Team 单元测试失败了,因为它没有接收到事件。该怎么办?

想到的一个解决方案是在 Team 之上引入一个额外的对象,该对象执行线程切换并保持原始单元测试的完整性,但我不喜欢在生产代码中引入复杂性以使单元测试成功的想法。

4

3 回答 3

4

当我用 完成 JUnit 测试时EventQueue.invokeLater,我已经将自己与那个邪恶的静态解耦了。invokeLater使用和isDispatchThread方法创建接口。对于生产,实施应该只是转发到EventQueue. 对于测试,请使用您自己的线程(可以为每个测试设置和拆除)。

其他一些随机建议:

  • 保持 GUI 尽可能薄。
  • 保持线程出其他一切,其他一切出线程。
  • 怀疑任何声称是线程安全的东西。
于 2008-11-30T21:23:30.603 回答
2

也许您可以使用 easymock 来隔离您要测试的类,并让模拟对象接收事件并检查它们是否被触发。

我推荐 EasyMock:http ://www.easymock.org/

从您的故事来看,您的单元测试更像是集成测试,而且非常复杂。如果是这种情况,请尝试简化和隔离。您可能已经阅读过http://junit.sourceforge.net/doc/testinfected/testing.htm

我希望这有帮助。

于 2008-11-30T20:55:49.783 回答
2

想到的一个解决方案是在 Team 之上引入一个额外的对象,该对象执行线程切换并保持原始单元测试的完整性,但我不喜欢在生产代码中引入复杂性只是为了使单元测试成功的想法。

我不知道这里是否是这种情况,但我经常发现我添加的“复杂性”实际上是更高级别的抽象,可以改进代码。

模拟对象背后的最初想法不是使单元测试更容易,而是“接口发现”,以创建代表通用语言中的抽象的接口,而不是在 API 级别工作。

于 2008-11-30T22:05:46.163 回答