【问题标题】:Handle Swing events in JUnit test在 JUnit 测试中处理 Swing 事件
【发布时间】:2008-11-30 20:05:39
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java unit-testing swing events junit


    【解决方案1】:

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

    其他一些随机建议:

    • 使 GUI 尽可能地薄。
    • 让其他所有内容都保持线程化,并让其他所有事情都不再线程化。
    • 怀疑任何声称是线程安全的东西。

    【讨论】:

    • 我喜欢你的建议,尤其是第二点。您引入接口的建议可能是要走的路。尽管如此,我还是觉得有点不舒服,因为我必须“只是”为了测试一些东西。
    【解决方案2】:

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

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

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

    我希望这会有所帮助。

    【讨论】:

    • 你说得对,我测试的不止一个类。我试图实现的是验证多个进程之间的通信是否可以达到团队级别。这是我要测试的对象之间的交互,我需要考虑找到另一种方法。感谢您的建议。
    【解决方案3】:

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

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

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

    【讨论】:

    • 我同意复杂性和功能抽象,但在这种情况下,我“仅”处理线程问题,这些问题可以通过在 UI 线程上做大多数事情来轻松解决,除了这使得测试更加困难。感谢您让我重新思考我的抽象!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    相关资源
    最近更新 更多