Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JUnit测试上下文中使用OSGi声明性服务_Java_Junit_Osgi_Declarative Services - Fatal编程技术网

Java 在JUnit测试上下文中使用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在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