【问题标题】:Unit-Testing OSGi-Components单元测试 OSGi 组件
【发布时间】:2011-10-23 16:00:49
【问题描述】:

我目前正在考虑“如何设计一个 OSGi 组件,以便使用 jUnit 和 Mockito 等框架轻松为其编写测试”

Mocking inter-bundle-dependencies 非常容易,因为 OSGi 加强了 DIP (依赖倒置原则) 并且通常存在注入器方法(例如 setter)。
但是捆绑内部依赖项呢?

例如查看this case。现在我想把它带入一个 OSGi 上下文中......我们想在 OSGi 平台中提供任何类型的网络协议作为声明性服务,并想编写单元测试来测试直接与套接字对象。

如果我们将套接字创建重构为一个单独但仍捆绑内部 POJO (Plain Old Java Object) 类,我们应该如何将其注入协议实现中?

  • 在单元测试中,我们可以简单地使用 setter 方法,但谁会在 OSGi 容器中为我们执行此操作?
  • 子类化测试类并覆盖创建者方法只有在测试类未声明为最终类时才有效。

【问题讨论】:

    标签: java unit-testing osgi dependency-inversion


    【解决方案1】:

    严格来说,测试与 OSGi 容器的交互是一种集成测试。为此,您可以使用Pax Exam,它有点难以掌握,但效果非常好(特别是如果您使用 maven 和/或 karaf 功能)。

    此外,您还可以使用TinyBundles,它可以在您的测试中动态创建可部署的包/片段(非常酷)来模拟其他包/片段,以确保包间集成,而无需构建完整的环境。

    对于单元或小规模集成测试(即没有容器),如果需要,您可以只模拟 BundleContext(或者如果使用 DS 则 ComponentContext)。

    对于您在要点中的问题,我有点不清楚。如果有内部 POJO,那么您有责任通过 setter 连接依赖关系,否则如果它暴露给 OSGi 服务注册表,则依赖关系由框架(DS 或 ServiceTracker)解析。

    还继承某些东西以覆盖创建者方法意味着您不再测试原始类 - 这是代码异味 - 尝试重构它以将创建者代码作为单独的类(构造函数或设置器)传递,然后这个可以独立测试新的创建者代码(创建套接字)(不考虑 OSGi 甚至将使用它的协议类)。

    【讨论】:

    • 如果我在 OSGi 容器中运行的 OSGi 组件中使用 POJO,则组件本身必须创建 POJO 的实例,例如在构造函数代码中,因为容器无法注入它。我应该如何在单元测试中拦截这个过程?当然,我可以创建一个 setter 方法来覆盖组件中先前创建的 POJO,但这也有一些代码味道。 “我们真的像在容器中运行一样测试组件的代码吗?”可能会发生一些副作用,例如在构造函数代码中调用 POJO 并破坏我的测试。
    • 我想我跟着,你有一个 Pojo 在它的构造函数(或作为初始化字段)中创建其他 pojo,例如创建套接字的协议类?如果是这种情况,那么您需要将 Socket 的创建与您的 Protocol 类分开 - 通过作为构造函数 arg 传递或使用 setter 应用(但从 Protocol 类中删除任何 Sockets 的创建)。这样,您传入一个模拟的 Socket 进行单元测试,而为您的包创建一个 SocketServiceFactory 返回真实的套接字(生产),并为容器测试模拟此服务以返回模拟套接字
    • 完美。使用透明的 ServiceFactory 正是我想要的。以前我认为 ServiceFactories 和 ComponentFactories 是一样的。 ;)
    • 酷,祝你好运,编码愉快 =)(你也介意对答案投票吗,谢谢)
    • 好吧,我还有一个问题。 ;) 我目前正在使用 BundleContext.registerService 注册服务工厂。是否有可能让框架在我自己的工厂创建的实例中注入其他服务?
    猜你喜欢
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2018-03-04
    • 2019-04-18
    • 2016-10-19
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多