Java 在JUnit测试上下文中使用OSGi声明性服务
我试图弄清楚如何使用JUnit在OSGi中实现多捆绑包集成测试 对于集成测试,我指的是实例化捆绑包的子集,以自动验证该子系统中的功能 我们正在运行Equinox并使用Eclipse作为工具链。Eclipse提供了“作为JUnit插件运行”选项,该选项启动OSGi框架并实例化配置包,因此我想这是应该遵循的路径,但我没有找到将DS引用注入测试的方法。 我见过使用ServiceTracker作为一种编程方式来访问不同的服务包,但这超出了使用DS的目的,不是吗 我刚刚开始使用OSGI,所以我想我只是缺少了一些可以让我将多包测试组合在一起的难题 有什么想法吗 谢谢你,杰拉德Java 在JUnit测试上下文中使用OSGi声明性服务,java,junit,osgi,declarative-services,Java,Junit,Osgi,Declarative Services,我试图弄清楚如何使用JUnit在OSGi中实现多捆绑包集成测试 对于集成测试,我指的是实例化捆绑包的子集,以自动验证该子系统中的功能 我们正在运行Equinox并使用Eclipse作为工具链。Eclipse提供了“作为JUnit插件运行”选项,该选项启动OSGi框架并实例化配置包,因此我想这是应该遵循的路径,但我没有找到将DS引用注入测试的方法。 我见过使用ServiceTracker作为一种编程方式来访问不同的服务包,但这超出了使用DS的目的,不是吗 我刚刚开始使用OSGI,所以我想我只是缺少
*编辑:解决方案* 在进一步研究了这个问题之后,我终于找到了如何使用JUnit插件特性将这个多包集成测试放在适当的位置: 为了使动态服务注入工作,必须创建一个服务定义文件,在该文件中必须声明注入的依赖项,就像使用DS时通常所做的那样。 该文件(通常)位于
OSGI-INF/
目录下。e、 g.OSGI-INF/service.xml
service.xml必须声明此测试所需的依赖项,但不提供自己的服务:
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">
<implementation class="com.test.functionaltest.MyTester"/>
<reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>
</scr:component>
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">
<implementation class="com.test.functionaltest.MyTester"/>
<reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>
</scr:component>
请注意,fooService
引用需要是静态的,以允许在OSGi和JUnit执行上下文之间共享服务引用。CountDownLatch为安全发布此共享引用提供了高级同步机制
然后,应在测试执行之前添加依赖项检查:
@Before
public void dependencyCheck() {
// Wait for OSGi dependencies
try {
dependencyLatch.await(10, TimeUnit.SECONDS);
// Dependencies fulfilled
} catch (InterruptedException ex) {
fail("OSGi dependencies unfulfilled");
}
}
@Before
public void dependencyCheck() {
// Wait for OSGi dependencies
try {
dependencyLatch.await(10, TimeUnit.SECONDS);
// Dependencies fulfilled
} catch (InterruptedException ex) {
fail("OSGi dependencies unfulfilled");
}
}
通过这种方式,Junit框架等待OSGi DS服务注入依赖项,或者在超时后失败
我花了很长时间才完全弄明白这一点。我希望这能为以后的程序员同事们省去一些麻烦。我不熟悉您提到的Eclipse工具,但我们已经成功地将其用于集成测试。如果您熟悉Maven,那么at的POM可能会帮助您入门,并且看起来也是一个不错的起点
通过允许bundle在运行时向OSGi框架提供JUnit测试,在这种情况下也会有所帮助,如果您的项目生成了可用于测试的可运行jar,这将非常有用。您可以使用运行配置上的选项卡进行设置 因此,右键单击,选择“运行方式”,选择“运行配置…”,双击“JUnit插件测试”,然后在插件选项卡上添加您的依赖项-与普通启动器基本相同 一些链接:
而且我想,掌握org.apache.felix.scr.ScrService并主动等待组件变为活动状态会更干净一些。该接口由equinox和felix实现
和。*编辑:解决方案* 在进一步研究了这个问题之后,我终于找到了如何使用JUnit插件特性将这个多包集成测试放在适当的位置: 为了使动态服务注入工作,必须创建一个服务定义文件,在该文件中必须声明注入的依赖项,就像使用DS时通常所做的那样。 该文件(通常)位于
OSGI-INF/
目录下。e、 g.OSGI-INF/service.xml
service.xml必须声明此测试所需的依赖项,但不提供自己的服务:
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">
<implementation class="com.test.functionaltest.MyTester"/>
<reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>
</scr:component>
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">
<implementation class="com.test.functionaltest.MyTester"/>
<reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>
</scr:component>
请注意,fooService
引用需要是静态的,以允许在OSGi和JUnit执行上下文之间共享服务引用。CountDownLatch为安全发布此共享引用提供了高级同步机制
然后,应在测试执行之前添加依赖项检查:
@Before
public void dependencyCheck() {
// Wait for OSGi dependencies
try {
dependencyLatch.await(10, TimeUnit.SECONDS);
// Dependencies fulfilled
} catch (InterruptedException ex) {
fail("OSGi dependencies unfulfilled");
}
}
@Before
public void dependencyCheck() {
// Wait for OSGi dependencies
try {
dependencyLatch.await(10, TimeUnit.SECONDS);
// Dependencies fulfilled
} catch (InterruptedException ex) {
fail("OSGi dependencies unfulfilled");
}
}
通过这种方式,Junit框架等待OSGi DS服务注入依赖项,或者在超时后失败
我花了很长时间才完全弄明白这一点。我希望这能为以后的程序员同事们省去一些麻烦。我认为在上述解决方案中,倒计时锁存器是不必要的 问题是DS上下文中的JUnit为每个JUnitSet类实例化了自己的JUnitSet类。第一个DS上下文实例化JUnitTest类并为FooService调用绑定onFooServiceUp,但在此之后,JUnit实例化自己的JUnitTest类,而不调用绑定方法onFooServiceUp。在这种情况下,JUnitTest中的FooService不可用
如果您将FooService声明为static(正如您所做的那样),并在方法onFooServiceUp中赋值,则不需要使用CountDownLatch进行构造 当然,这是我提到的“作为JUnit插件运行”选项,但它似乎不足以注入声明性服务。i、 e.您在哪里声明绑定方法?还有一个关于背景的问题。注入会发生在Junit上下文上吗?如果是这样,该机制是如何工作的?与在应用程序中使用DS相同。您需要添加DS捆绑包,这将在加载其他捆绑包时扫描它们并管理布线。DS绑定在捆绑包jar中OSGI-INF的组件xml中声明。有关在Eclipse插件项目中使用DS的说明,请参阅。谢谢你的建议。在Junit插件运行的上下文中不会调用DS注入方法。我的OSG-INF声明正确。谢谢你的建议。它需要的不仅仅是配置。我已经用我找到的解决方案更新了我的问题。@maasg很高兴你把它整理好了,很高兴看到你发布了你的解决方案+1