OSGi服务测试助手:ServiceRegistrationRule

OSGi服务测试可以有效避免与悬挂的服务引用有关的问题。 就像我在写简单服务贡献验证中所承诺的那样,这次我引入了一个JUnit规则 ,该规则有助于测试组件之间的交互。

OSGi服务测试组件交互

假设我们有一个服务,该服务通知根据whiteboard-pattern绑定的相关观察者。 就像上一篇文章中一样,我们ServiceImpl有一个Service声明和ServiceImpl 。 另外,我们支持ServiceListener ,应在特定操作时通知此服务。

为了表示这样的动作,我们使用名为Service#execute()的方法声明来扩展示例的服务接口:

public interface Service {
  void execute();
}

除了实现此execute方法之外,贡献类还必须提供绑定和取消绑定ServiceListener引用的功能:

public class ServiceImpl
  implements Service
{
  public void execute() {
    [...]
  }

  public void bind( ServiceListener listener ) {
    [...]
  }

  public void unbind( ServiceListener listener ) {
    [...]
  }
}

作为通知目的地,回调类型ServiceListener提供了一个称为ServiceListener#executed()的方法声明:

public interface ServiceListener {
  void executed();
}

要完成设置,我们必须注册服务组件,我们将通过声明式服务再次进行此操作。 请注意附加的0..n参考声明:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component
  xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
  immediate="true" 
  name="Implementation of Service API">
  <implementation class="com.codeaffine.example.core.ServiceImpl"/>
  <service<
    <provide interface="com.codeaffine.example.api.Service"/>
  </service>
  <reference 
    bind="bind" 
    unbind="unbind"
    cardinality="0..n"
    interface="com.codeaffine.example.api.ServiceListener"
    name="ServiceListener"
    policy="dynamic" />
</scr:component>

现在的问题是:我们如何测试监听器的取消绑定/绑定是否正常工作以及是否按预期分派了通知? 基本思想是注册一个ServiceListener 间谍并在实际的服务实现上触发Service#execute

间谍记录了要execute调用,并允许验证绑定和通知是否按预期工作。 一旦确定了这一点,我们就可以继续进行注册并注销主要注册的间谍,并确认没有收到有关后续操作事件的通知。 这样可以确保解除绑定也按计划进行。

但是,这种情况下的测试夹具通常需要一些OSGi样板。 为了减少混乱,我编写了一个小的JUnit规则,该规则可以简化服务注册并在每次测试运行后自动执行服务注册表清理。

服务注册规则

与其他所有JUnit TestRule ,必须在我们的PDE测试 TestRule ServiceRegistrationRule作为公共字段提供。 注意给定测试用例的类实例,规则如何使用参数化的构造函数。 此引用用于获取适当的BundleContext用于服务注销/注册。

@Rule
public final ServiceRegistrationRule serviceRegistration
  = new ServiceRegistrationRule( getClass() );

private ServiceListener listener;
private Service service;

@Before
public void setUp() {
  service = collectServices( Service.class, ServiceImpl.class ).get( 0 );
  listener = mock( ServiceListener.class );
}

隐式测试安装程序使用我在 ServiceCollector介绍的ServiceCollector检索正在测试的注册服务 。 使用mockito将侦听器DOC创建为间谍。 上述第一个测试方案如下所示:

@Test
public void executeNotification() {
  serviceRegistration.register( ServiceListener.class, listener );

  service.execute();

  verify( listener ).executed();
}

很简单,不是吗?

请注意, ServiceRegistrationRule负责清理并从服务注册表中删除间谍服务。 为了便于测试解除绑定的情况,规则的register方法返回服务注册的句柄:

@Test
public void executeAfterListenerRemoval() {
  Registration registration
    = serviceRegistration.register( ServiceListener.class, listener );
  registration.unregister();

  service.execute();

  verify( listener, never() ).executed();
}

第五行( registration.unregister() )从服务注册表中删除侦听器间谍。 这将触发解除绑定,并且永远不会调用侦听器。 当然,现实世界中的场景可以为多个侦听器注册,异常处理等添加其他测试,但是我认为这个概念已经明确了。

结论

到目前为止, ServiceRegistrationRule在我们当前的项目中证明了自己的作用。 它大大减少了样板,使测试更清洁并提高了可读性。 该类是Xiliary P2存储库的com.codeaffine.osgi.test.util功能的一部分: http ://fappel.github.io/xiliary

如果您想查看代码或提出问题,也可以查看Xiliary GitHub项目: https : //github.com/fappel/xiliary

对于其他所有内容,请随时使用下面的评论部分。 在后续文章中,我将说明如何使用集成的PDE-Tes​​ts来设置Maven-tycho版本。 这有点棘手,因为tycho不允许访问当前反应堆构建的束,因此请继续关注。

翻译自: https://www.javacodegeeks.com/2015/02/osgi-service-test-helper-serviceregistrationrule.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值